-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Python (continues issue/discussion #3) #7
Comments
Yeah, I did it. Now I just need to rename things. Hopefully nothing breaks. But I am quite pleased with my solution. What do you think? |
That's a good solution, much simpler than what I had in mind, just 2 things I'd change, the help (the numbers are not useful anymore) and moving the dict inside the class (I try to avoid global variables, in this case they are only used in this class). I'm not sure if it works but you could also try assigning |
Yes, that works, to, but I figured, we might need it again. A previous version did reuse it, so I wanted to cache this. BTW, how can I get rid of this, we set the loglevel, so why is there a default in this place? simply removing the assignment and only leaving |
You'll need to refactor a bit, the issue is handler.setLevel(verbosity). Maybe make handler a property and change the level of it in the method set_verbosity, we only have 1 handler anyways, so it should work. |
Yes, I just noticed, set_verbosity() or now set_loglevel() is only used once. Does that really need to be a method? |
Hmm, and I now still get at least one INFO at -v warning |
You could do for example, from the main function : log.logger.setLevel(20) log.handler.setLevel(20), but if you move the handler.setLevel into the Log.set_level, then you kill 2 birds with 1 stone, since you just need to call log.set_level(20) and it will set both. |
The issue is the Log class is the first instanced, since it's required by everything else, but at that point we've not parsed any arguments, so we set the default loglevel to 20 until we've parsed the arguments. |
That doesn't sound right. We should make sure the arguments get parsed first, then. argparse emits its own messages anyway. |
That's what I originally wanted, but I wasn't sure if you were set on using the logger for the argument parsing class so I tried to accommodate, but if we both agree, then we should remove logger from the argument parser to make things a bit simpler. |
If we change it, then we can do in the main function: Utils, checkArgs, Log, then set the Log instance on Utils.log |
So, you're saying everything related to logging needs to go from the argparser, right? |
But wait, how can we then set the loglevel at the argparsing stage? |
Oops, was going to edit (deleted). I think it would make the code a bit more simple. |
Oh crap, how can I reopen this? |
Ah, found it ;) |
Yes, but since we need to set verbosity by a method, Log must be instanciated at the argparsing stage already, or am I missing something? Is this maybe a Catch 22 situation? And if so, how to solve it? |
Basically, we make a Utils instance in main (utils = Utils()) then we check the args (checkArgs(utils)) in main again, then we set the Utils instance log property: utils.log = Log(utils.loglevel) in main also. utils.loglevel is a property we set in checkArgs (self.utils.loglevel = args.loglevel) Something like that? |
Um, OK, have to digest this first I think. This OOP stuff still makes my head hurt. ;) |
Think of it like a array kind of: x = [0 =[0 = "z"], 1 = [0 = "a", 1 = "b"]] x[0][0] is "z" class X: class 0: class 1: x = X() |
In a more practical example: class Options: def init(self): Here I change the Options.maximum_size from 100 to 50self.maximum_size = 50 def change_max_size(self, size): options = Options() # I create a instance of options |
You're making it worse, ow. :-D Maybe I just need a break. BTW, what does __get_ref_loudness have to do in Checkargs()? |
It doesn't but I didn't see a better place to put it, I figured it was something that should only be run once, and Checkargs() is erased from memory after it's ran (since we don't store it in a variable), if we put it in Utils() for example, then it will remain in memory until the program exits (since we pass utils instance to ThreadMkvrg). |
OK, but from a logical POV it does not make sense. It makes it really hard for me to grasp, what's going on and why. |
We might want to rename CheckArgs, since it also checks binaries, maybe call it Setup or something (you're better at names than me). |
Oh no, it does too many things I think. Let's make smaller objects. And have a real structure. Isn't that the point of OOP? Have something parse the arguments, then something that checks those for sanity and if the program has all it needs. Or check first, if the binaries are in place. If not, why parse arguments? Fail then and there. |
|
Thx, I am just putting it together. |
Done. Looks good so far. |
I found a PHP library which reads matroska files (and tags), I was trying to figure out how it works, I think I got a decent idea, but it's a pain, it had to go through every byte checking if the bytes match those in the page you listed above, there's no order to how those can be done in a matroska so it has to do conditionals on every byte and change byte offset on the file handle every time accordingly. I was hoping I could just write something simple in python just to read the tags, but that's not possible, going through everything is required, to make sure the byte offset is at the right position. |
Oh my, looks like it's not worth it. I am still convinced that using the json from mkvinfo and conversion to and from xml can work. We should have everything we need to find the right place to put our data into the json object. Then convert it back to XML and feed that to mkvpropedit. Maybe in the beginning just write all tags back with |
Yeah if you want to see the nightmare, here it is : https://github.com/JamesHeinrich/getID3/blob/master/getid3/module.audio-video.matroska.php#L497 |
LOL, it's only ~800 lines of code. No biggy. :P |
@005a58d, I think that does not work as expected, I think the first conditional is always true. |
This might be a way to do it: https://stackoverflow.com/questions/3389574/check-if-multiple-strings-exist-in-another-string |
Yeah, I thought so myself, reverted it already. |
Didn't use any() though. I think that is overkill for only 2 strings. |
Actually use a method of MkxFile().
Again, the code does not get used. I hope however that the idea gets across.
Now we actually leverage MatroskaFile(), but only, for the time being, to basically replicate the prior behaviour. The goal remains to multiprocess on an audio track level, so multiple tracks of one and the same file can be processed concurrently.
Think I am getting the hang of super(), hopefully. Also, some minor cleanup, i.e. use self.utils.log.. instead of self.log.. to avoid confusion.
since to be processed it must be an actual file of type matroska, which this class guarantees for its objects, move the methods that deal with something involving a path here.
Just had a look at your commits, fine work! I'm still alive, just a bit busy right now. |
Thanks, I am glad you like it. I've learned a great deal in the past few days. And I have failed, a lot. ;) |
I think it's a good idea, if you do it now it might be easier than trying to do it later. |
Make the path of an MkxFile private and provide accessor. Also, check on initialization that we have a file at our hands, raise exception if not. This way we can just try and except through the list of arguments, could maybe leverage that for the recursive search maybe.
I consider this a semi-major change. Prior to this we always created two instances of MatoroskaFile(), one while filling utils.files and checking if it is a matroska and then when actually processing in process_thread(). But at that stage we have all the information we need already. So pass the path of the file, which is guaranteed to be a matroska into the queue. Since utils.files has now become an ordered dictionary, it also holds an entire MatroskaFile object with all the methods attached. Before we just threw away that object when we only tried initializing the object and then only take its path and put that in utils.files. While that might hurt memory usage I think it is worth it for not having to do the checking twice.
Huh, somewhere along the way loglevel setting went missing. I've put in some debug messages which I still cannot see at -v debug. :( |
FYI, I am currently experimenting with the json module to get the old tags. I think, once we get to the stage where we can just add our tags without destroying prior unrelated ones, we have something to work with. |
Indeed, there's a lack of tools when it comes to that. Btw, just some quick testing with mkvinfo:
This shows the size of all the EBML entries:
By seeking, we can get some data, for example "Segment information":
Here's the output (string representation and hex under):
As we can see, the Also near the end we have: Maybe we can get the tags like this, by seeking to the appropriate location. |
I am using the json data one gets when running
|
OK, updated my double-post. |
Just FYI, I am still alive. I experimented with above code a little and it looked very promising until I tried to run it on python3. It seems there is fundamental change between python2 and 3 when it comes to processing the json data. I still haven't figured out exactly, where it goes wrong. Strictly speaking StringIO should not be necessary for this, so I went without it, because it was the first to complain. The code runs fine without it in python2 but now json.decode() trips over something else. I'll keep at it, though, but maybe python2 compatibility was not the best of ideas, after all. :( On the plus side, I am able to store the original tags in a nice dict construct like |
Yeah the inconsistencies between python 2 and 3 are annoying. |
No description provided.
The text was updated successfully, but these errors were encountered: