[LC67] Working on a YouTube Video Editor in Sublime

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] LOL the sublime tax phonetics Oh dad nerd here welcome to tonight's livestream where we're trying something just a little bit different both in the content of what we're doing here such as it is and also in the actual way that we're working the stream here I spent a fair amount of time last week building as I may have mentioned my last week my own version of herbs 25 point 0.8 which required a little bit of jiggering on my part because there's a library that wraps the X protocol and for the first time in five years that library had a release and immediately the absorptive a version of the library presumably it's doing new things that they need for something that they added in version 25 point 0.3 I think or two because 25 point 0.1 certainly didn't require now I haven't seen anything of its like as yet but nevertheless that was required in order to get things like preferences working again and that was sort of a tricky operation because Lib XE be the thing that X applications used to talk to the server that's not really something you want to just swap out when you have other applications so we we hand compiled and our own version of Lib xcb and associated libraries so that there could be a newer version for obscene still maintain compatibility with other things then I've been thinking about doing this for quite some time now and that is working up a control panel of sorts for the WebSocket implementation that is in observing called herbs WebSocket that allows you to control pretty much every aspect of it which I had played with a little bit in the past but there weren't really any good clients and didn't order him to play with it there's a brand-spanking-new version that came out not too long ago and I built myself a version of that which required some hand tweaking because it needs a newer version of C++ then I have available on my system and installing whole new compiler to chains tool chains isn't in the cards in the general sense so apparently I think I bumped the mic there so we had to do some tweaking on the code for that plug-in and then I created myself a web socket plug in a web socket API rather for being able to switch in and out of scenes and suchlike and I was working on this all the way up until midnight last night I did a bunch of testing everything seemed to be okay so this is gonna be the first stream trial run using this and of course I want to do more work on this this is really quite crude the nice thing about this is I can run it on my iPad which is a little bit bigger and it's giving me information like a real-time CPU outlay and it allows me to switch between scenes without having to manually change things in obso something I should have done quite some time ago so now one of the things that this is also working for on our behalf is making sure that the appropriate transition is used at the correct time and that the headset mic is muted and unmuted as we move through scenes as appropriate like I said I did test this last night and everything seemed to work let's hope that everything is going to work fine here as well and I'm say I'm still referring slightly over here to the stream dashboard on my Mac here because it's got a hardwired connection and the the iPad doesn't I don't want to saturate the Wi-Fi network too much with that because the the live-streaming booth if you will in YouTube studio seems to require you to actually see a live preview of the video every time I try to pause it in there that's when things start to go weird that as far as I've seen so as I leave well enough alone in that regard now speaking of YouTube related things what we have been working on in the streams for the last little bit is working on over I doubt it working towards a new build I really got an itch right there I felt like I got a hair or something see how crazy that drives me but we've been working on override on it I still have some more work to do on that but with all the other stuff that I was doing I didn't really have enough time to give enough thought to how to proceed per se with that particular offshore operation man this is rough so because there's if there's a few interface related things that I'd like to work on there or that I need to decide on and I really have a lot of time to think about it so instead what we're going to do is work some on a package I've been working on a personal package for myself that's not really publicly available anywhere named YouTube editor this is kind of related to something that I did in November if you were following the blog for that we're gonna try and kick that up a little bit into some new action and see how far we get I have ideas for things that I'd like to do but we'll see you know exactly how far we actually get for some of these things before we get excited although I have worked on things like the piano plug-in and sodoku and such we're not actually making a youtube video editor as in actually editing frames of video more being able to look at the descriptions and titles and tags in existing videos or set up to create new ones is the idea that we're going for here so this is something that I would find super handy for working with my own YouTube channel because YouTube studio it's better the new experience is better than the classic one but still not that great okay everything seems to be fine stream health is remaining healthy I'm not seeing any weird flashes of blue out of the corner there so let's go ahead and dive into the stream proper and see how well our little control panel here actually works hello fellow sublime tips for next oh dear oh dear welcome to the live stream proper for the 16th of June January February March April May June yeah that's right I'm one of those people that when someone asks me my age I tell them my birthday and tell them to work out the math of themselves we're going to be working today on a YouTube editing package that's not a package for actually editing literal YouTube videos frame by frame or anything of that nature but actually a more working with the titles descriptions and tags in existing videos and newer ones this is a sort of an add-on if you will to something I was working on one of my projects in November of last year which I was calling youtuber Iser at the time now I'm calling it YouTube editor as of right now this isn't yet it's not publicly visible at the current time it because it does require a sublime text for but also it has requirements for some dependencies which I have set up which are also private for the time being pending changes to package control and getting dependencies to work in this particular thing so essentially much like the piano plug-in that we were working on a few streams back this is something that a person if they had the source code for could set stuff up there's a lot of setup that has to go on behind the scenes you have to know how to use the google app dashboard to get yourself a client secrets you have to know how to install your own dependencies and stuff so for right now it's not public and that really I don't know that this would be useful to anybody other than me anyway so you know I'm sure that will change and we'll go so and the other thing if you didn't watch the pre entry stream introduction one other thing that we're testing out here in this stream is I created a web dashboard using of all things node-red because I don't really like nodejs related things but it had a WebSocket implementation that that makes it fairly easy to plug some stuff together so I spent a little bit of time and what I have down here on my iPad just under the screen if you see me looking down in that general direction now where the keyboard is is a panel that tells me the connection status between this and herbs whether it's recording streaming CPU usage memory disk and a scene switcher which will hopefully once and for all get rid of various problems although the buttons are roughly the size of my finger so chances are good at some point I'm going to hit something in the wrong place but they should also stop those problems that we've had from time to time with the stinger in transition being triggered when it's not supposed to and sources muting themselves accidentally because part of the switcher is doing stuff like that so in any case I should also point out that for the purposes of this dream something I'm playing with here is the file icons package by braver the color one just to add some different icon than the standard ones this isn't something I normally do but it's something I've been playing with a little bit because I do a lot of nodejs stuff at works much as I don't necessarily want to and no programs have just such an enormous number of extra files laying around that even something as simplistic as having an icon on a file that's slightly different amongst a bunch of other files it's gonna make as far as I've been able to tell a life a little bit easier in that regard so I installed it here as well because i sync my settings and for test purposes and we'll see what we think about this I'm currently using the Monica Pro classic colors game here from the Amano Kai Pro package I have the package not installed because it's an obnoxious theme in as much as it doesn't guard itself from breaking your icon so if you have it installed you will have no icons unless you're using that theme or some other thing that maybe might override it depending on the package name so I've removed that I'm trying to decide do I want to use this newer monic I Pro color scheme that has tons more rules in it than other the the mono kinda chips with sublime or do I just want to stick with it and if I decide that I like it then I'd buy the package and just keep using this color scheme that streamed scheme that I extracted out of it um jury's still out on that one but in any case mmm we are just coming and get rolling because we've been talking for just a few minutes here we got I just wanted to make sure everything was settled or it seemed to be with what it wasn't was working on actually as a matter of fact I'm going to go a little bit like this let me see okay one of the things I wanted to work on hopefully that No okay one of the things I wanted to work on was adding some audio filters so I can even things out a little bit which is tricky because Oggs under linux doesn't support the the audio plugins that i want to VST plugins' hopefully that's something that's coming soon but maybe I can so I can't EQ anything but I might be able to adjust volume levels and such and maybe make things sound a little bit better that way something I want to work on anyway what we're working on here in this dream is something that I have been working on a little bit if you watched the repository for my project last year I worked on a few different projects for example a Sudoku a plug-in to allow you to on-the-fly gzip and undies files while you're working on them so you could open a gzip file and sublime edit it and when you save it it's Jesus back where it came from one of those things was a plug-in and package I was referring to as YouTube riser and the purpose of YouTube riser is entirely this I could say list videos right now it's called YouTube editor because I'm changing it a little bit but it was called YouTube riser back then and when we hit this we see a list of every video as it currently exists on my channel which includes as we can see here some behind the scenes how the sausage is made kind of stuff in that we can see that I have an end cards template for getting end cards into my videos and a couple of other videos in here but for example I could do plug-in 101 and see all of the videos here which for some reason are not sorted particularly well title wise which is maybe something we need to work on but say I was interested in if someone asked a question just the other day on the sidebar and seeing link icon and they didn't know what it was I can easily use that command pop in here say side I find the video that I know has the appropriate topic your sublime sidebar questions answered hit enter and the link for that is now copied to the clipboard so if I was to paste it in that's the link that would take me to that makes it easier to share videos with people so that's something I worked on during the member project doing that which was fraught with peril to say the least and then just recently I'm trying to go through older videos and do things like make the descriptions better make the tags better and things of that nature so to that end we could do this that this is very nascent I've only done a little bit of work on this if I hit this I get a new window as we can see right here now this top part is the title of the video where we might say say common common questions 45:46 this is the title of the video like so and hitting tab will jump us to the middle where we can type in the description of our video and you can't whoops there we go we can't currently invoke snippets in here due to the way but the key binding is currently working but as we can see here as we're working on stuff the first whoops turn the caps lock the first paragraph if you will is a green color and everything else is not you can put hash tags you know in here as well that's just something that YouTube allows you to do okay they don't call them hash tags but nevertheless hmm and I think it also highlights links so like so and they're even underlined in this particular case and down here this would be where the tags go like so and we can see that so rod I've got now is the syntax highlighting the idea being that if I wanted to edit the information on a particular video I'd hit a key not unlike the one that we did to whoops don't do it in that one to list videos like so and when we get the list of videos instead of copying the link to it it would open a window like this after getting the title and the body and the tags and then I could type what I like in here and when I hit the save key in any of the fields it would push the information back up and actually modify the metadata associated with that video in fact we could even do another thing here by having a column here that has the thumbnail for this video loaded as well so there's a few things that I'd like to do with this particular thing and we can see I got a bunch of to do stuff here because there are some best practices when working with YouTube videos and descriptions like what the maximum length of a title is so if you go more than gets clipped and there's a certain amount of characters at their maximum description how we need to know how much text is displayed before the fold that's when you look at the description of a video and it'll have that read more of course what you want to try to do is put something that describes the video make someone wants to watch it in the first part because that's parts always going to be visible and then you know the rest there's a lot of other stuff like you know try to hit the appropriate keyword a few times so that YouTube knows then the search results are irrelevant tags there's a maximum length - how many tab characters there are and what their lengths are so these are all things that we would like to have working in this plugin to help us know that we're doing something wrong like the description is too long or things of that nature and that the to-do items in here aren't all necessarily plug-in related per se but it's information that I found while I was looking for things like tags and what I discovered was the tags that 500 characters long an individual tag can't be more than 30 characters or it will be deemed invalid and perhaps more interestingly tags with spaces in them count as an a length of extra 2 characters because when YouTube stores the information the way that it stores it if the tag has a space and it has to wrap it in double quotes so that it knows where the tag ends which is weird because commas are the thing that separate tags and as a result the lacs will tag length would actually be to more than the 30 character so your tags if they have spaces in them might potentially be only 28 characters kind of hard to say but so I just found all that information and dumped it in here but perhaps in this first thing because I think we're probably gonna work on this a couple of times we said go over a little bit about what this actually does if you didn't watch the wiki on the dough vembur project per se and you wouldn't really know any but stuff about this and I have you know play with it a little bit so whoops that is what we're trying to do let's go ahead and hide the sidebar for now here in the editor this is the main plugin now we're gonna see there's a couple of interesting things here I just go scan through here these things are less interesting so first of all in order to talk to a youtube channel you need to have a client ID and a client secret and various other things for the OAuth flow whoops pardon me which is how you gain access to being able to access the data API for a YouTube channel now there's a fair amount you can do if you don't have that information but you can't drill into specifics on you know certain channels you because or any channel than your own per se so the thing that this does is get the list of videos that I personally have uploaded to my channel that information is available only to me it's not available to the world at large so we have to prove to YouTube that we have access to that data in order to be able to access it whereas if you just wanted to search YouTube to find a particular video or find a particular channel find a particular user all that sort of stuff that's something that's not per user per se that's just something that you could do even on the YouTube page so those sorts of things those are those sorts of read-only operations you don't require this sort of stuff and most of what I did in my my dev ember project was fighting with the apply brer ease required for getting that sort of thing working and learning about more about OAuth and I'm actually going to jump in here because this is the actual thing itself but if we see we have a dependency on Google API client which is something that I also created if we have to go to the I actually have it here now let this go to the package directory to make sure that it is what I think it is so the YouTube editor is that right here that's just a sim link to that a directory where we were just in but if we looked in Google API client this is the sublime dependency at this is dependency that I created and we're going to go into all like so and actually I said in the introduction that this is using newer version of Python but actually it's not it's a Python 3.3 and older so this technically would work in sublime text 3 I believe but there's trickiness to getting dependencies to work in that version so I'm using the older one we can see here the sheer number of libraries that are required in order to talk to a Google OAuth thing here and so there is a fair amount of stuff here so what I did was just bang it all into one dependency to be able to get at this sort of information let's go ahead to size that back down and exit on out of there now because we're not gonna need that so that sets up the various things that we need because basically what you have to do is go into the Google API dashboard set up a project say you're using OAuth apply it get the appropriate token set everything up that's going to give you information that these api's need to communicate back and forth with the Google endpoints in this case the YouTube data API in order to be able to exchange back and forth and get the actual information that you're interested in so when you do something we could actually do here and say actually we'll do it from the menu for YouTube editor let's see there's a log in and the log out and I can't pick login right now because I'm already logged in that would actually fire up her browser and then say ask me to log into a Google account then ask me which of the accounts associated with that to use and then ask me are you sure you want to allow this application to have access to your YouTube information it can do blah blah blah say yes or no we've all seen that sort of thing if you do something like log in with Google or log in with Facebook or log in with github all that sort of thing they do that sort of that's the OAuth flow and once you say yes we get a token that we can use to make requests and that particular token only lasts for 24 hours anybody that has that token is essentially us you provided in a request and it is you so it only lasts for 24 hours and then it expires and you have to use a refresh token and that token in order to collect a brand-new token to continue going and this involves you know exchanges back and forth and it's very complicated and annoying particularly because there's secrets that identify your application and the documentation makes it sound like if you're doing an installed application you should do it this way you still have to keep that information secret even though they acknowledge that it's impossible to do so and also the reason why another reason why this isn't sort of publicly available per se is that Google is not a fan of allowing someone with open source to have this sort of information in it so I could provide this package as it sits in the repository right now which requires anybody that wants to use it to go through all of the rigmarole of setting up the login in order to access their own page but I couldn't for example set up a service on my own website and have everybody log in through that and talk to it back and forth through the plug-in and make this available to anybody that wants to use it I'm not allowed to do that because it's open source now in order to make all those calls we're going to need to talk over the network to make web calls and wait for responses to come back and as we know from looking at a lot of stuff here when you execute a command sublime hangs until that command finishes executing and similarly when you respond to an event like a file being loaded or saved or whatever do you when you're responding to the event the whole of sublime is hung unless you use the async variant that runs in a separate thread so in order to not hang sublime while we wait for exchanges to go back and forth to get this selection of videos that are on the channel we need to have a thread so here and plug in loaded and plug in unloaded we have the simple job of creating a network manager thread that's global a network manager object pardon me that doesn't create the thread there's one network manager we're gonna look at that in just a minute whose job it is to manage all of the communications between our plugin and the YouTube API and when the plugin is unloaded if we created that we ask the network manager to shut down and if you watched yesterday's video on plug-in 101 and the plug-in life cycle you know that this is going to make sure that the network manager doesn't get created until the plugin is loaded so everything is ready to go and every time the plug-in gets reloaded for example during development if there is an existing thing it will get shut down now the core of a lot of things that happen in here is this YouTube request class which as we can see here abstracts away the common portions of using the network manager to make a request and get an answer back so if we went through this when you execute the run method now the reason this is a mixin command as a class or sarios we're gonna see that you could blend into any command so it has its own methods that would be overriding what would exists inside of the command classes so it's run method takes any and all arguments because it doesn't know what you're going to do and it asks the network manager if we're authorized or not and authorized means that we have cached locally information that we could use in a request to provide information that says I am the onat nerd sublime text tutorials channel attached to this Google account and the owner of that has said that they allow access to this information and if we don't have that then we call the request method to request authorization otherwise we call the authorized method and this is as I say an abstraction because everything needs to do this every command that might want to make a request needs to know if it's authorized so the very first time you invoke this if you're not already authorized it makes an authorized request like so now the magic of this is this is a request that tells well actually we could look out right here I guess this is the the line of code that executes green yellow it's weird that executes we ask the network manager to make a request and we're passing it a particular Handler and such we give it a set of information it gets a result and it dispatches something back to us as we can see here it's going to call self dot result and that method is going to get the request that was made whether or not it worked on what the actual result was so we make the authorize a an authorization request and basically the handler as we're using it here which is this field that we're providing to this method tells it that when it gets a response back it should call the internal off method which stores the information and then says self authorized which is the same as what this is doing now the internal off method only gets returned back on success as we can see here if if the request success is succeeded then we want to execute the handler that was provided which again is internal off otherwise invoke the error method instead so if we attempted to login and it didn't work then we would get this saying there was a error popping up otherwise this code would invoke the internal auth which calls underscore authorized and that's something that each of these subclasses that uses this mix in actually uses to be able to do something and this is something that's going to work regardless for any sort of request we'd like to make so for example here's the authorized command which subclasses YouTube requests and an application command because they're only ever needs to be one of these things and it's run method just needs to call self request authorize because that's the thing that we actually wanted to do here and automatically making these call to self dot request is making this call which is doing all of the work up here to actually dispatch the request we said we want to get the authorized method called which is this one so automatically all we have to do is say that and this and if the six the data that comes back works this gets executed otherwise the error dialog pops up this command doesn't even need to know about it the command enables or disables itself whether or not this network manager has any credentials loaded and logout is a similar but it asks you if you want to actually do this or not so when you run the command it's gonna have by default the value of false here for this method if you asks you that if you actually want to do this pops the dialogue and if you say you want to do it then it runs its own command again but with force to true so that once the dialogue is closed this command runs forces true it called makes the deauthorized request and everything happens just like that now here this is due to the magic of the abstraction that we did above absolutely everything we need to be able to do something in a to be able to actually make a request and you see these ones are different than these these have a run method the authorized and deauthorized they override this one in here because they're actually related to the getting of the authorization so they take special actions but actually requesting data we don't actually need to do anything here because the rapper is going to make sure that we are authorized if we're not authorized it's going to ask for authorization which is either gonna pop up the dialog box or it's going to invoke the underscore authorized method giving the request and the result which allows us to just say hey I want the list of uploads playlist and if we get the response to upload playlist then we make a new request for get me the contents of that playlist and when the contents of the playlist comes in we get the active window and show a quick panel with a lambda that picks the particularly do which sets the clipboard and says the status message of your coffee which is why when I say list videos like so I could pick say for example this if you look down in the status area URL copied that is just like that now this all runs into thread and the very first time you run this you will see a message similar to this YouTube editor spinning up YouTube thread because the network manager is responsible for managing the thread that is running in the background but it doesn't start it right away it only does it if you're actually going to be doing something otherwise you're just creating a thread for no reason and then this is the thing that is the new thing that I added which creates a window with a set layout and there there we go for that now the interesting part for this and we're gonna go ahead and open that file here even though it's open in the right so we can see it a little bit better because there's a fair amount of information that goes into this and probably for the purposes of this maybe this isn't something that's technically interesting but there's been a lot of questions recently on the stack overflow I'm sorry on the discord and somebody was straight excuse me it has asked in the past about stat on Stack Overflow about how you do kind of like this what do you do if you want to create a plugin that needs to have a thread running in the background because you if you need to take any sort of lengthy operation you don't want to do it inside of the run method of a command because then Sublime's api will hang while the command is executing for example in the early versions of youtuber Iser every time you listed the video sublime would hang during that exchange of please give me the YouTube the the ID for the uploads YouTube playlist for this particular user fall apply please give me the contents of that playlist so I can do something with it every time you did that everything would just hang you couldn't scroll you couldn't type nothing not what you want events can be made asynchronous if you want to do something in the like respond to a file being opened or saved asynchronously if you have to take a longer action because sublime has two internal threads it has the main thread and the async thread so if you did something in the async thread that's running off to the side the UI still continues running problem with that is there's one async thread that's shared by your plugin his plug-in his plug in every plugin plus the sublime set timeout async api method all those things run on one thread and they're basically run in order of as things are being submitted so even though you want to use something like that for a longer action you don't want to do it for a lot of frequent longer actions generally speaking because if that's the case and there's a lot of plugins doing stuff then performance of everything suffers because if my plugin in response to a file being loaded kicks off an async operation that's gonna take you know a minute that's one minute that no other async event will work anything that relies on set timeout async to schedule something is going to be deferred for that whole period of time so that's not really what we want so we actually do need to spin up a Python thread in order to do something like this and that is the basis of all of the code in here so I thought it would be fun to sort of show this and then the next time somebody asks we have something to actually refer to in that particular regard rambley the HOH it may be so this is actually something that isn't being invoked any well it is being invoked right now it's not supposed to be invoked but there's just a little bit of magic here as we can see here this should actually be done whenever anything needs any of these values so realistically the way that I implemented this in the YouTuber Iser in my original implementation this network code was inside of a folder inside of the YouTuber Iser thing and it would be imported from there instead and there was a method that would actually have this information instead of coming from settings file as it does here it would be hard-coded and client ID and client secret well client ID at least one of these is the thing you absolutely need to keep completely unique props even both of them I kind of forget at this point because if any of somebody basically the Google end of things knows that this ID and this secret together represents this plug-in and anybody that has that information can make requests as this plug-in it's something that's associated with my user my Google user which means that anything that makes these requests I'm responsible for so you want to keep this secret because someone could do something malicious and there's no way to prove it you're not the one that did it now the way it was implemented initially this was actually inlined in the code because the documentation mentions that there are cases for example you need to keep this absolutely positively secret or someone can know who you are however that doesn't work if you need to have this information in an application that is installed by the user because in that case there's no way to hide this information from them be reading between the lines there is even in that case you still have to keep secret but they don't make it sound like that so for the purposes of actually using something like this in a stream I swap this to actually load this information from a settings file and set so we can look at the code and hopefully that information doesn't leak out so that's a little bit of a hack in this particular case not necessarily related to threading this thing at all we have a log method here that generates log messages to the console and possibly also a that should say decorated to be perfectly honest and I did that I don't think anything is currently using it but the idea idea is anytime this a plug-in needs to generate any outfit output to for debugging information for example that message that said spending up YouTube thread it does it through this method and that's just because whenever you write anything to the console who knows who sent it unless it's prefixed for example if you prefixed it with 'b YouTube editor in this particular case which is why I use this particular pattern and in this case if you were to provide the panel option it would create an output panel and put the information into that panel so that you could have sort of a list of stuff that happened which I was handy during debugging now we need to have in this particular case information on basically a token if you will the way the OAuth flow works is you make a request the site challenges you you provide a response sort of thing and what you get back is a magic opaque token that you include in every request you make and as long as you have that token you're authorized to do a thing and that token represents this user logged in and provided these credentials and those things expire so every now and then you need to request a new one we need to have the information about that token and how we Qwest a new one but we don't want that information to get out because much like the same way if the client secret got out someone could make a request as us if that token got out then someone could make a request and you're getting someone's getting access to something they shouldn't have so we actually store this information in a file and the cache folder named YouTube editor credentials and we pull that information out if it's there we can store it in the token the Refresh token and ID token as we can see here it's also encrypted as well now one of the things that this should be doing is asking you for a password to encrypt it but for the purposes of right now it's encrypting it automatically with just the password password because until things get rolling and you make requests work that's just extra stuff so that's something that needs to be done but this also uses the PD KDF I used to remember what that was but basically it's a thing that makes it you know incrementally harder to guess or crack the actual password there so here we can get the cached credentials out we can see it's actually decrypting that information now this is one of the libraries that had to be installed in here in order for this to actually work and then we pull out the information into a credentials object and shoot it back this is responsible for actually creating things now this is something that's actually part of the Google library the cache API request library thing it seems that given a service name at an API version and in this case our credentials which I don't like the way that's spaced out so this is going tweak that like yeah given that information it's reloading that's what should be killing the actual thread when we do that as well but that's not logged at the current time it actually creates sort of like a pseudo object whose methods you can call we'll see that in just a and here we get into the actual basics of how this thing is actually working we have a request object which is just a simple wrapper it's something it's a hashable dictionary that doesn't throw exceptions when you attempt to access a key that doesn't exist and it inherently knows a name that's associated with it so when you create one of these you create a name you create a handler and then any other Keys you want and the the name and the handler key are kept separate in fields everything else is just an item in there and as we can see here it's set up so that if you ask a request for a field that doesn't have that just returns none instead of throwing an error and here's our network manager which is responsible for starting up the network thread shutting down the network thread if the network thread is actually alive with just this bit here tells it's the thread that it should be shut down and then we have various information in here like asking it to we have credentials for the user which means that has the user logged in previously so we don't have to ask them again if this is not set then using any command would open the browser and make you log in otherwise it just pulls that information and tries to use it are we actually authorized the plug-in caches this information and callback is part of the mechanism and request as part of the mechanism so what's going to happen is you ask the network manager please make a request this is the request object which is one of those dictionaries we saw just a moment ago this is the callback that you should execute when that request finishes success or failure and this is something that is specific to here some requests that this makes the results are cached so internally inside of the network manager so that the next time you make a request by the same name you just get the same results back so we can force it to fetch information again even if we already have it and this is just so that if you have one two five ten twenty a hundred requests that want to have information cast why make them responsible for cashing it when they're all going through one common endpoint so let's go ahead and do that in here hangs I gotta go like so that's uh yeah it's my right that's right I don't interact with the webcam that often and the magic of this is whatever callback you provide the request actually gets told to invoke this one and then once it's done it actually calls the user callback so we sort of interpose ourselves you make a request this method is called and then this method is called if that makes sense you can sort of trace through how that sort of logic works and then the magic of this is this the network thread when it starts up has a list of requests then it knows how to fulfill and what method in the class is responsible for doing those things and the actual runtime of this thing itself waits to see is the thread event set and if it's not then it loops inside here but as soon as it is set it terminates and that's why the method in the network manager that is responsible for shutting down sets the thread event and then waits 1/4 of a second to join that thread to know that it has successfully shutdown but apart from that what does it actually do it gets a request from the queue that is blocking with a timeout and then it handles the actual request this has a timeout here specifically because if this if this blocks and doesn't have a timeout then the loop won't be able to determine that the thread needs to be terminated and when we call handle request what what does that do it takes a request object off of the queue and gets the request and the callback makes the call and then sets up the handler now what we're actually doing here is a little bit of this action this request map get is accessing this so that if the request was authorized then it gets the value of self dot authenticate for example when we handle the request that's what handler is if it's none then someone made a request that we don't know it's not in that list of dicks things in the dictionary so it was an error otherwise we're gonna set the success to be true and actually run that Handler and grab the result and if there is an error doing that then it's not a success it's a failure capture the result as an error string and lastly down here will you set timeout to call the callback which is the thing that was provided in the request we can see that right here I just need to scroll up for that this is just sort of a cheap easy way to take this from running inside of the network thread and get it running inside of the main thread of sublime so that all events that this error callbacks that this invokes are invoked inside of the main thread of sublime and then it marks this particular task is being done and then it would go back and do it again so in the case of the authorized method or the authenticate method we get the get authenticated service deauthorize oh here's here's the one that we're using in their uploads playlist when this code here wants the list of uploads the uploads playlist for example it calls self request playlist contents with the playlist ID of something sorry I guess let's let's trace this right from the actual beginnings I think that'll make this all a little bit clearer here so we invoke this command list videos now what's that going to do that is going to execute the run method in our YouTube requests because that's one of the subclasses it's run method asks if we're authorized and if we are authorized it will immediately execute the underscore authorized method otherwise it invokes it makes a request to authorize us and request is asking the network manager which is creating an object which and putting it on a queue for that thread to be able to handle otherwise it actually calls underscore authorized so when we run the list videos command it asks for the information for uploads playlist let's pretend we're already authorized which is true in this case because I logged in prior to the stream it calls self dot request self dot request up here is this method here calls a network manager to create a request object for that particular request and the handler which is a string that is going to tell the eventual returned what method it needs to call it takes all other arguments and just gives them to it so that the handler in the network thread uses that to know what's actually supposed to happen here and then the callback is self dot result which is this method so what happened there over here in the network managers someone made the request so it wasn't already cached so the request wasn't in the cache then it calls if it was it calls that it's not and the thread is a lot not already alive so it calls the start up we see the big console saying hey I started up the thread if the if we had previously made this request then the result would be cached and as a result we would just immediately invoke the call back with whatever we got last time it doesn't even need to go into a thread right otherwise we do need to make a request if the network threads not alive well now's the time to start it if the network thread is alive we're good to go this makes sure that the threads not always running it's only running of one actually takes to YouTube action because otherwise we're just wasting cycles and then we add a request to the request queue that says the request is the string the abuser provided which in this case is that upload playlist thing we can see that right here in this window as a matter of fact and that's the thing that's ultimately going to get called and the callback is please invoke this callback method up here to tell us that things are done that method this message then is inside of the queue so we come all the way down here this is inside of the thread this thread is just sitting here saying is there a request yet no do I have to quit no it's a request yet no do I have to quit yet no is a request yet yes I pulled something out and a request and a request gets the request and the callback that's going to be the string that represents what request needs to be made and what code should be executed when the request has completed we assume success and no results ask the request map which is up here in the constructor if someone asked for uploads playlist what method should be called and the answer to that is these self-thought uploads playlist method and the callback is the thing that should actually happen so it gets the that the answer is not none this is a known request so it calls that function and the content of that is the uploads playlist that's the thing we see over here ask the YouTube channel list to give us the whoops sorry yeah uploads playlist right yes excuse me this is asking the particular channel associated with the YouTube account that's currently logged in please give me the contents of the upload playlist which is the list of videos that have been uploaded to the channel by the user whether they're public or private or whatever and please execute this response this hangs right here it stops it shoots off it fetches it gets a response back and then we gather the information and return it back and this will potentially fall off at the bottom if there isn't a channel in the this thing then this is the user that's logged in that hasn't provided uploaded any videos yet the return value is none so we would come all the way back down to handle request we have the actual value here it didn't throw any sort of exception like you're not allowed to do that or this request is garbage or it timed out or anything along those lines so we call self sublime dot set timeout please call the callback that the user requested and this method is currently running inside of the network thread calling set timeout scheduled sublime to execute this callback function on the main thread as soon as possible and then we tell the cue that we got that made the request that we're done handling it now it's it's done it's good so then it knows whether or not the queue is actually empty or not a moment passes the main thread finishes doing whatever it's doing maybe just finished executing a command maybe you typed a character who knows and it calls the actual callback method that was provided now up here when we made the actual request we saved the actual callback that the user provided and we're specified that please execute our callback so now that we have the list of videos on the channel it worked so we cache the results so that the next time someone makes this call we can just immediately invoke the callback we don't have to go through all that rigmarole again people don't normally upload a YouTube video that often and if we wanted to we could make the request with refreshed set to true in which case this would be ignored and it would do everything anyway if the there are certain requests that need to be handled specially otherwise we just call the user callback the user callback was the thing that was provided way over here in the actual command itself when we asked for to get the list of videos we told it to invoke the uploads playlist method which is this one which kicks off a whole new requests to actually get the contents of the playlist that was returned which does all of the stuff so that's the whole for how this the whole thing works so there's a thread running in the background we give it messages using a thread safe queue that thread can communicate information back to us by using sublime dot set timeout to get something to run in the main thread that's just sort of a nicer way of transferring things back otherwise you would have to constantly pull a thread safe queue to see if there's actually a result yet that doesn't seem like a particularly good idea at all and we also have the ability to start that thread only when it's needed and to stop it when needed as well so if I was to save this we can see it saying terminating the YouTube thread YouTube thread has terminated because of the plug-in unloaded in this particular thing and if I said I wanted to list videos we can see it's saying spinning up the network thread and it's going to take a second because it had to ask for the ID for the playlist that represents uploads and then ask for the contents of that playlist and then we get it right here and now every time we do it it's cached for the next time so I spent most of my devourer working that stuff out there's still a few things that need to happen in here for example that password still needs to be something that happens but one thing we do want to play with and I think I have a tab over here somewhere is it that one no is it this one yes let's see I'm gonna grab that and put it over here whoops and maximize it up for the time being we'll go ahead and does that close it up yes so what we're trying to do in this particular case is get the information on an actual video because we actually want to be able to say like I said something like new window for YouTube editor but actually have it you pop this up but give us the title of a video the description of a video when the tags that are associated with a particular video so we need to be able to that information out to be able to do something like that and the way we do something like that is with this videos list item here and we can play with the API a little bit we'll see if we can implement it in the code because the other stuff was based on an example and it's been six months since I did something with that so I remember how it works I don't remember how it works if that makes any sense I know logically what it's doing but we'll get to that in just a moment so the first thing I guess we should look at this so common use cases for this method it's a way to hide this thing yes well maybe we don't want to do that and because we're gonna need to try that in a second well let's see what happens oh yeah there we go there's a try it so retrieve information about a specific video using the ID parameter to identify the video or you can do it for a group of videos if you want to do that sort of like a batch or get just a list of YouTube's most popular videos now here's that for example of the list of videos liked by the user that authorized the API request which is the person who's actually logged in but we actually want is list by video ID which is how I got to that so call this method to see the API request and response so let's go ahead and zoom that out like so now we could see over here I forgot that this was here so this is neat if we wanted to do this in Python this is what the code would actually look like now a lot of this is boilerplate and interesting to note this although I didn't get it from here is how I actually came up with all of the code that we just looked at I started with a very simple example of this now in the original example the information was in a JSON file there's also one that does something else this is what we actually used to figure out who's actually logged in it's calling run console here what this would actually do if we ran this inside of a Python console would be to open a browser and ask a person to go to a page where it would take a string and paste it in and then you authorize the application and you come back and enter the result that they gave and that's how the token comes back and then it calls YouTube to this discovery dot build this is responsible for basically building an object that knows how to do something based on the API that's provided which in this case as we can see is the YouTube so if we wanted to get any list of videos this is the call what we would make so we're going to need that in just a minute and it needs an ID and we execute that request give it a response so if we actually wanted to try this what we could do is come over here and say list videos like so and then say say the the most recent video I was actually five I didn't think it was hmm let's say Wow p101 oh six which is this one here so this is getting sublime text platform information we can see the ID it's part of the link so for our purposes here we're gonna do that that copied the link to the video and I can come over here and paste it in here but we don't want this this is the ID value of the video if it's the the V equals on a YouTube watch page is the thing that you know youtube links ago to and here's a various information that we can provide in here if we want and the thing we want is in this case the snippet contents and statistics that's because of that sample so we have all of that stuff we're going to go ahead and execute this it's going to ask me to choose an account to continue whoops I'm going to say I want to use this account and this thing here and allow this to access this particular information and here's the result that we can expect back if we actually do something like this we're going to get this JSON object let's go ahead and copy that out and paste it in over here why don't we Jason data like so so this is a video list response and here's the items it's a YouTube video this is the ID of the video this is when it was published the channel that it's on the title the description is one big long string lists thumbnails so if we wanted to actually display the thumbnail for one of these things we could the title of the channel here's all the tags that are associated with that and some other information it's a two dimensional HD video with no captions with no license content I guess hopefully none of this information is super secret by any stretch of the imagination so if we wanted to actually get this kind of information this is how we might actually pull something like that off so the first thing we might do is actually go into the networking code itself and for the purposes of this we'll do it over here playlist contents is similar to what we want to do here so actually yeah let's just let's do it over in this one cuz it'll be a little bit nicer like so so we're going to need a new thing here so we're going to say what are we actually doing in this particular request we're getting let's go ahead and now we'll leave that open for the time being what was it called hmm it's in here in this particular code videos videos dot list not particularly good name so let's say video let's call it video details let's say and the method that should be invoked for this is self dot video details like so and then we would find the playlist content method we're gonna I'm going to actually copy that to make sure that I spell it correctly playlist contents is the thing here so let's copy this whole method like so come back up here and change it to video details for requests giving it given the ID of video for this for user fetch the details for that video for editing purposes now I'm not entirely sure I haven't looked into how we might actually use this to upload to update stuff it may require more information than we're actually going to be returning here and let's go ahead and that's videos dot list so details request is equal to self dot YouTube videos dot lists and we need to provide what did we say part equals this actually let's do it for just let's just say content details let's say we actually need to know the information that would be used here yeah well we'll use all three of them for right now and then we'll play with it in just a moment in the other part so what's that called come part equals this and ID equals request dot video ID like so and how did how is it returned here just executed and printed huh oh I see while details request execute and this would be I'm not entirely sure that is the correct thing we can for the purposes of this that'll be fine let's go ahead and print details list response like so so we'll actually get to see what sort of result it actually makes now we added the thing there we added that handler so that should be all we need to do there if we came back to here and now we need to create a whole new one of these and oops I should have copied that part too to separate my command fetch the information on a particular video on a user's YouTube channel and then you know more stuff will happen later we don't want to call uploads playlist we want to call get details and we would name this underscore get details as an implementation note the way this works is you provide it the name of the method that should be invoked instead of the actual callback because it's a little bit nicer to look at than constantly having to create a lambda or something along those lines and it prepends and underscore on it so that it's possible to define a request that doesn't collide with a method name so the request that we want to make actually no we do need to do that stuff don't we we do need I forgot we do need the uploads playlist we do need to playlist contents we do need to select a video but when we select a video the result of that is going to be something that we don't necessarily want playlist contents is appending the title and that so this is not necessarily the greatest way to pull this off this sort of handling should be happening in the other part but this is again this is something that was a proof of concept so for our purposes here we could say select video video instead of doing that the thing that gets copied here is the actual URL of the video and if we actually tested I guess we needed to actually do it don't we most videos like so pick to say for example that one we end up with that so video ID is going to be equal to video dot split at that the last item like so and then we can say self dot request and the request we want to make is the thing we just created which name I already forget video details and when we make the request we need to say that the video ID is equal to video ID like thus and for the purposes of this one this is why this method does this remember we are invoking this method refresh equals false is the default to make sure that it always caches the result of this for the purpose our purposes right now that's fine but going forward we probably want to pass true there because if we're actually editing these things every time we request it we want to make sure we have information that's up-to-date and we're going to go ahead and do this right mmm yes we're going to say someone's talking on the discord I'm just gonna pop in real quick package development any ideas why sublime might not be honoring autocomplete preserve order strict in this Auto completion and return a sorted list but the items are unsorted in the window well there's actually a link to that and that's just sort of a aside that's neither I'm hearing over there for the purposes of this let's go ahead and close that up I'm just always curious when someone pops into the discord and asks a question so the thing we're actually going to be invoking here is video details self request and the result and we just go ahead and just print results here we're not actually doing anything with it because we're not actually returning it yet we actually should not name that we should be say video details command so video details command and sublime commands we want this to say get video details this isn't something we're gonna keep because this isn't exactly how we want this to work we just need it to be you should just be video details like so okay so what's all of that in place and oh I broke it I broke it I broke it but online 2:05 and I did not do that there we go so we should be able to say why te get video details and it has to fetch that information down and let's say this one of my earlier videos introduction to override audit like so and list object has no attribute split Oh Krunk my bad video one split pardon me okay I'll have to do that all again fetch the information down huh CPU usage has calmed down nicely it's interesting sometimes it kicks up to 30% CPU and sometimes it hovers down around 20 I don't know what makes you do that so far everything seems to be working quite nice okay so we're gonna go ahead and pick that Oh [Music] unknown request video details oh I think I need to save that one first then this one one of those things that automatic package reload are made easier previously we try that one more time see if that actually fixes it otherwise I may have done something a little funky there still no huh all right well let's check and see what we did wrong did I name it something different in the not that one in the actual network thread video underscore details well I don't know it certainly looks like it's there oh this is actually broken so it's not loading oh all right shoot pay more attention to that pal there we go okay now do that loop do doop get video details all right let's do it for 106 and there is a metric ton of information so we have successfully pulled it down it's actually being printed inside of that actual method there so we'd want this to return back only the information that we're interested in so one thing we might want to check here just to see I'm gonna clear this console whoops that's word wrapped pardon me it's clear this well how many of those things did it return I get oh I guess that's not actually a list so don't do it a bunch of times that's probably unfortunate okay clear the console oh boy this one well we made that unhappy bro when all else fails quit and restart okay now let's not do that in the loop huh because clearly that's not what we want to do to do we just want this thus and it's probably not even a list of stuff well again what it actually returns doesn't matter because it's not gonna be loaded anyway okay there we go and here we do that so if we did do what were we saying get video details for spinning up the YouTube thread 106 there's exactly one and it stopped great this actually shouldn't return that it should return a list an object and the other thing should return an object with the information and then that should actually build it up but that's something we'll do later or perhaps I will do later because we are you know most of the way through this stream hopefully someone will find this this particular one interesting this is something I've wanted to work on for a while and never seem to find the time and everybody trying to kick off into doing more information in here for these things so the actual part is the part that we're interested in is that say anything no okay so let's close that to comma-separated list of one or more video resource properties that we want okay oh yeah that's right if the parameter identifies a property to do we might want title description tags that's exactly the only thing we want so that's probably the easiest way to go right so let's give that a try we come over to here and we say in the networking code that what we want is the title description and tags this might even just automatically return an object that we're interested in looking at to be out perfectly honest but if we hit that hmm that's not as interesting as it could be okay the ID the list of video IDs that were interested in right right right max results that do page token so this doesn't actually the part browser specifies a comma-separated list of one more video resource properties the API response will include to do how does one actually know sit down here did you do you not provide a request body oh here we go there's some stuff there are some errors there's a try it you know I guess there's probably some global list of crap that you can put into that thing to let it know what it is that you're interested in let's take it back to what it was before let's say we just included content details for this thing still nothing but if it was snippet and content details oh you know what I think we need to do this too otherwise it's not going to create the correct thing now that I think about it there we go tag kind caption false projection regular content rating licensed content has constant thumbnail alright so that has no useful information in it per se perhaps snippet is where it's at oops this one one two six my broadcast no language tags oh we're getting closer I probably should have cleared the console before I did that one so then it was more obvious let's try that really we're gonna play it that way now wasn't there just something there a second ago oh it's probably it's caching the empty result right okay I can dig it whoops I explained it but I still confused myself so if we turn off word wrap there's a bunch of stuff in here well because we can't do that we'll see kind items kind there's the I D there's the title there's the description there's the tags so that is the minimum amount of information that we're interested in and if we were to snag all of this like so and let's go ahead and say can ever remember curious concept go to town bring it back to here this is the information we have at our disposal so inside of the items array there's going to be exactly one thing because there's only one thing there's the list of tags that we're interested in there's the okay if we close up these snippets the snippet in the item has everything that we want for this which is the title the description which I imagine must have embedded new lines in it or something to do yes so we're actually we're actually pretty close to doing what we want here working a little bit better than they might have expected so let's go ahead and I'm gonna jump this over to here where it's probably gonna be harder for you guys to see it cuz my head's in the way but that I think is okay so this is separates the details for that videos so what we're actually gonna say is result is equal to a dictionary where the I D is equal to Oh before we do that yeah that's just how I did it before cool so I'm gonna do it the same way here just for stuff for item in details it's not actually a list response it's just a response details response just did I say dot items I just looked at the thing yes I did well I used single quotes and not double quotes working on note is really messed with my head we're gonna return an object and otherwise we're just going to return none microcell and we're gonna provide and the ID of this thing and we're going to provide a disco and we're gonna provide a description and we're gonna provide tags and the idea of this thing is item oh shoot item dot snippet item don't say dot info equals item video is equal to item snippet so we can say whoops the video ID oh shoot that's actually in the thing isn't it crap hi t is the item ID the title is the video title the description is the video description and the tags are the video tags I would imagine thus and we'll save that oh not how you do that huh what hast thou done wrong this is one of those situations where I'm messing up my head because I did a lot of node stuff so it's specifically mad online 466 oh because I did not put a comma on line 465 there we go so that saved that saved if we were to say get video details for spin up that thread spin it 106 there we go there's the tags list of stuff there's the title blue there's the description text and there's the ID of this thing now because we actually did this correctly if I was to hit this one more time and say 106 the answer is instant because it's cached and we could actually specify that it not do that so that's good I want to cycle back and fix the other thing as well as a matter of fact just for this might be kinda redundant on our part I'm not sure how much information playlist contents returns so let's go ahead and print playlist item like this okay so and we'll go ahead and do that and clear this console cuz there's gonna be a lot of stuff we're gonna turn off word wrap at the time being so if I said for example just list videos that's all we need to do here it is grabbing title information this is a list of things that it's doing if we came over here and bummed that in replaced incorrect quotes interesting so it has the title and the description but it doesn't have the tags interesting I wonder if there's a way to get that cuz then we wouldn't have to him return this information that way anyhow but let's go ahead and grab that and do what we did before I'm gonna go ahead and stick it over here like this just so we can look at that thing because I think we actually want is for this to return well that shouldn't be a list of sort of results you should just be results it should be the job of who's ever doing something with it to sort it now I remember now the reason why this is here is because there it could potentially do multiple pages and stuff so it has to keep asking that's why we sort of saw these sort of paging in like that which may or may not be an issue on its own so that's us printing it we don't need that we need details is equal to this and then we're gonna go ahead and stick this in here and say what did I call it in the other one did I call that video ID no I just called it ID didn't I so this should be well maybe that should be video ID that makes sense and then thank you that and that should both be this and then we can hang that over the snippet title and the video ID for the purposes of this let's also include the description she's gonna be a playlist items snippet inside of the snippet it would just be the description like so and that and that and then I'm gonna come at that line out and actually just say this results dot append that actually no we could do just to make our lives nicer video link could be equal to this and then instead of video ID we'd have to do this which is ugly but you know for the purposes of that this is where we get the next list of things so playlist item list request is do we need a next thing so if we told this to execute multiple pages it would keep creating a new request until eventually it got everything so if we did that we might discover that I didn't add a comment of this thing like so and here's the bit where we would say print results like so and then we have to also save that clear this council the thread has been terminated invent when we this list videos that command is going to be a very angry indeed um type error stream work right oh it's even more angry than I thought it would be I may have broken its ability to do more than one of these things but what we do get is the video ID with that a link to that title that we expect and the description so that's nice for the purposes of that results dot a pen so we don't need this anymore let's say these are all going into snippet to grab the information so we could say details equals playlist item snippet like so and then we could find all the instances of this and replace it with details uh-huh and video ID is equal to this so we could just say video ID and that so I think that gets us more or less to the point we're at right now and when we say list videos and there we go so video ID is still a thing it still got a link it still has a title unfortunate oh this is one big long thing because word wrap is turned on right okay so that is a lot of videos and not just one the problem now of course is that thing that gets the results back is not doing the right thing with it but that's okay so last videos would be this okay we're going to need to say I know this is equal to title link for video in results and then instead of results we just say item just like so and and hope when we pick it we should see a list of useless information which is exactly what we want except that did not oh it doesn't handle that correctly neat oh nice well fix that to UM the actual thing that we did is go ahead and just jump to present inhibit reorder does the thing right on it totally does the fields that we added in here our title and the video link so if we did video underscore link then I think we could grab that and that and do a little bit of this video title video video link maybe we don't name it video link I think we just name it link and ID we want ID title description link so what we want coming out of that that worked we want this to be like that and select video and I comma items so this would be index and items and if index is greater than or equal to zero and video equals items ID X and then we set the clipboard to video not video one video link should just be video like so that's the link URL copied and that should also be video link we want to set the clipboard to the text and that okay actually that was the title wasn't it it used to be the title and not the actual thing so I think that's why that was zero so that seems to work so if we did this and said that we wanted 106 so we have what looks like some stuff in here I hit cancel we don't get that error like we got a second to go the video list is cached now so that's handy we say we want 106 in here like so and oh shoot indices oh did I messed that up did I right right right I said I didn't need to fiddle that that should still be 1 & 0 I forgot I wasn't changing how that worked ok that's I think that should fix it that and 106 URL copied getting sublime text platform information and if we paste it we have a thing and if we went over to here and pasted it we would get the appropriate video perfect so we've fixed whoops we fixed that we no longer need this irritating print in here like this and now for video details we can say ID title description tags like so and that also means that we would this is list videos right so in this one when we get playlist contents we need these two lines as we see there and select the video should start with this and then we can just say self request video ID equals oh shoot I guess we still need to do it that way anyhow don't we due to the way that I structured that that's okay no idea special crap yeah well in that case let's put this one back to the way it was over here let's say that and that should be video ID and so should this one like so I think that's probably nicer so we're going ahead and save that I'll save that will clear this console to test what we got going on if we were to open this and say lists videos we get a list we say 106 it copied the getting sublime text platform information to the console and if we did the same thing and said get video details and picked 106 I'll shoot an error occurred i spudge something up video details video ID equals anyway you know what did I not I didn't fix this one save that save that and go ahead and get the details for when it pops 106 still no hmm what the hell am I doing wrong here video I did video details oh I guess that one was supposed to be yeah that one should be ID maybe I just didn't reload the whole thing actually you know what let's try this I don't think editor and networking alright okay so let's go ahead and clear that console we're getting really close to the end of the stream here and we could say get video details I'm doing something so dumb here video link is still that part right now let's print video ID one of the things I was thinking about adding to my interface is a button I can push with a type of pop-up when there's a terrible bug okay so that part seems to be correct details a request load that load that and I'm gonna be so angry when I eventually spot the dumb thing that I did here there is a request object so it's definitely getting this far let's go ahead and double check I didn't you provided an ID of the thing and the part and it does the bit for you the request was properly constructed I keep confusing myself with that one let's drink some coffee and ponder let's try that because it might be failing and catching the exception for other reasons doesn't seem to have the request that I'm passing in is video ID equals video ID which is a thing that we know that it is this takes a video details request for request video ID [Music] actually might even try this print alright don't do that print request just to make absolutely for sure that it's getting to the point where we want it to handlers video details name is video details so video underscore ID is totally a thing it got a response but the response is potentially an error so that is better it's this I changed it one place too many I think that is the reason why that does not work they call an ID I don't call it ID and there we have it cool okay so let's go ahead and fix this up playlist content does what we want video details we don't want to print got a response response or item or request we just wanted to return the actual thing or none which it's doing for this so here's what we're gonna do and we'll see if we can work this out and then that'll be the end of the stream because we've hit more or less the two-hour mark this is kind of what I wanted to do but I did want to talk through how you do stuff with an external thread and and things of that nature here I'm so when this gets invoked the result we get is actually this nice object that's going to give us the information that we're interested in so what we gonna do here is if we were to find must be down here this is going to do some stuff we can say YouTube editor new window so here's what we're gonna do we're going to say window is equal to sublime dive active window Oh actually we're just gonna say sublime active window run command YouTube editor new window and then window is equal to sublime dot active window then we can say the title view is equal to window dot - do I need to do a little bit of this and say index in group mm-hmm focus group gnome groups you can group views in group active sheet in group active view in group yeah actually no will say views in group is what we're gonna do here no actually no but we know what we're doing active view in group and give it a group sweet that's what we want so we're gonna come over here the the title view is the first group the description view is equal to the second group and the tag whew all right title desk tag and we'll go ahead and add those out active viewing group two like so whoops and then we can say title view dot run command this isn't how we would do this generally because we don't let's see it's gonna put the cursor at the end append and whoops characters our result title right do I believe this when I named it yep okay so we're gonna go ahead and grab those two paste them in there and the description is going to be and okay let's see what we get out of this if we get video details for video 106 getting sublime text platform information and there's that information there's some nice links in there and there's the tags we have successfully done the thing now what we could also do in here while I'm remembering and I'm gonna go ahead and close that is we can say window dot settings dot set video ID to the result video ID like this so that if we did that again and said you know get video details actually that's uh let's do this one it's gonna pull that up there's some information there and if I did window window dot settings that get and setting we got to get is the video ID we get that so the idea there is when you invoke this it creates the window it puts the information in there like so and gives it the nice syntax highlighting and stuff it stores in the window the setting that is the video ID so if we ever wanted to create something where you know pressing save in here triggers out uploading and replacing information on the video with what we see inside of this thing then we have the video ID that we need in order to push that information back up the other way which isn't something that we've played with here per se but it is something that has going to happen potentially in next week's stream so I think we made a good progress here we cleaned up a little bit of stuff in here and managed to actually make requests to to YouTube them which is gonna make a lot of stuff that we're trying to do in this particular pack is easier now this is something I want to do I want to be able to save that information back up I want to be able to populate a template in if I was going to create a new video and in that case there's more things we need to do like auto completion of title formats we also and this is something that I actually wasn't tending to do until we decided to get into network stuff is an event listener that marks anything after the 100 characters in the title as an error and the same thing for a description and something that marks anything after the first X characters in a line now this says the first two three lines total I think there's actually a character count and what we would do is grab the first line the first sentence out of the description and any characters that are longer than that in that first line we would highlight them so that we know that they're not going to be seen and it's gonna go for a read more and not the right place we're going to detect if tags are too long or if the whole tank buffer is too long so we can get things going and when we get those new windows now if we said yte new window it's the web cam being full screen that kicks this thing up to 30% CPU oops that's yte I'm just I'm just typing something in here for a new window when we get a new window that pops up we'd want to be able to autocomplete the title of something and then also have an autocomplete for our body based on various templates because all of my common questions videos have a certain template and all the plug-in 101 videos have a template and so on and that's gonna do it for this stream and what we were just talking about there those are videos that drop on my alternate channel which is linked down in the description of this live stream and all live streams where I do a weekly supply of text tutorial video we're currently alternating between doing tutorial videos for sublime in general and for plugin 101 where we go into more detail actually describing plug-in development in a way that we generally don't in the live streams unless someone pops into the chat and asks a question which you can do if you watch these live ask any questions you like in the chat and if I can I'll answer them if you have any questions after the fact you can drop them into a description and I'll try to answer those as maybe it'll be the topic of a new livestream or the topic of a new sublime text tutorial video on the other channel as well I believe the next video that's coming up is a rapid-fire question answer about sin taxes and how they're used in salon so I can't remember the exact thing but sort of a style of not this last video with the previous one on common questions about the sublime text sidebar we're going to do one of those and then into some more I'll plug in 101 the week afterward so make sure you subscribe to this channel if you want to see live streams and the other channel if you want to see the tutorials subscribe to both hey it's free use the buttons down below so that you'll get recognized to share this with people you think might be interested in learning about sublime text package development but that's gonna do it for this stream until next Tuesday stream we're probably going to be working on this a little bit more doing some Auto completions maybe some phantoms things of that nature I'm not entirely sure this is owed at nerd thanking you for watching if you have been and please have a sublime day
Info
Channel: Terence Martin
Views: 124
Rating: undefined out of 5
Keywords:
Id: STKEtOiwdH0
Channel Id: undefined
Length: 130min 50sec (7850 seconds)
Published: Wed Jun 17 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.