Reset default prefs

Is there a way to reset a single or even all preferences to their default values from within a plugin?

 

I ask this because with the FindUnmatched plugin I have a field of valid media extensions to scan for and the user could change it to 'all' to check for all extensions. I have since added a checkbox to scan for all extensions. I would like to reset the valid extensions pref if the user had it set to 'all'.

 

 

Thanks,

Chris

Maybe nuke Library/P M S/Plug-in Support/Preferences/com.plexapp.plugins.findUnmatch.xml

Not sure though, but try it

/T

I was hoping for a built in method. I really don’t want to delete the file because of the other settings. I can always edit the file directly if I have to.

I was hoping for a built in method. I really don't want to delete the file because of the other settings. I can always edit the file directly if I have to.

Standby...Reversed it, and will check in code soon....

And This is IMHO kinda nice, and AFAIK, undocumented ;)

/Tommy

Standby...Reversed it, and will check in code soon....

And This is IMHO kinda nice, and AFAIK, undocumented ;)

/Tommy

Checked into branch Tommy-work....

Take a peek and merge if agree

/T

Checked into branch Tommy-work....

Take a peek and merge if agree

/T

And updated this one to reflect it:

https://forums.plex.tv/topic/87348-undocumented-functionality-and-tips-tricks/?p=506039

/Tommy

And for people watching this:

Chris even managed to find a tweak to my method, making it even more cool

As soon as he check in his code, I'll update this:

https://forums.plex.tv/topic/87348-undocumented-functionality-and-tips-tricks/?p=506039

with his additions.

But Basic, no need to have defaults stored in more place than one

/T

Basically it boils down to doing a URL request. Like this:

u = urllib.urlopen('http://{PMS_IP}:32400/:/plugins/{PLUGIN STRING}/prefs/set?{VARIABLE}={VALUE}')

Replace what's in the {}

An example from FindUnmatched:

u = urllib.urlopen('http://localhost:32400/:/plugins/com.plexapp.plugins.findUnmatch/prefs/set?ALL_EXTENSIONS=True')

You can reset it to default by setting an empty value like:

u = urllib.urlopen('http://localhost:32400/:/plugins/com.plexapp.plugins.findUnmatch/prefs/set?VALID_EXTENSIONS=')

Chris

Edit:

A better method is to use the HTTP.Request that is in the framework.

HTTP.Request('http://localhost:32400/:/plugins/com.plexapp.plugins.findUnmatch/prefs/set?VARIABLE=VALUE', immediate=True)

To set multiple Prefs with one request:

HTTP.Request('http://localhost:32400/:/plugins/com.plexapp.plugins.findUnmatch/prefs/set?VARIABLE1=VALUE1&VARIABLE2=VALUE2', immediate=True)

Note the "&" between the two.

Has anyone tried this using HTTP.Request and actually setting a value, like a string?

I had to do this:

PLEX_PREFS   = 'http://localhost:32400/:/plugins/com.plexapp.plugins.vlcplayer/prefs/set?'
 
try:
    u = HTTP.Request(PLEX_PREFS+'fq_file='+fq_file.replace(' ', '%20'), immediate=True, timeout=0.2).load()
except:
    u = None
 
Without a .load() or .content nothing happens.  When it is done, PMS does not answer, so there is a timeout problem.
This should not be this difficult.

To be frank here....

I found this, but used the urllib when doing so

Later, both me and Chris was informed about the HTTP api, which was unknown to us, so, an dmy bad here...added without testing to this

So in order to correct the doc....please tell me what .content and .load() does?

All I can say so far, is that with urllib and urllib2, it rocks, as seen in the "Find UnMatched" plug-in

/Tommy

Also, it is documented in dane22's doc: https://forums.plex.tv/topic/87348-undocumented-functionality-and-tips-tricks/

Edit: I haven't changed it in FundUnmatched yet.

The UnsupportedAppStore does use it:

81: HTTP.Request('http://localhost:32400/:/plugins/com.plexapp.plugins.unsupportedappstore/prefs/set?clear_dict=False', immediate=True)

Chris

I edited the answer above to use the HTTP.Request framework.

Chris

Did you do any testing and investigate the results?

I did some more testing.

BTW, the .load() causes the request to be executed.  The immediate=True also does this.  The .content not only causes the request to occur, it provides the returned page content as the return value.

I have to use the timeout, or I have to wait for the default timeout (several seconds)  A timeout of 0.1 seconds works also (not a surprise for the loopback interface).

Even if I use the timeout, which returns execution to the channel, the spinning wheel remains for a lot longer and the log shows a timeout dump for the request.  I am using the local PMS web server interface.  Not the most reliable, I know.  But I don't believe that should change the log file results this much.

The only way I found to avoid all of this is to wrap it in a try block.  Then the timeout does its thing and the try block prevents the timeout dump in the log file.  And everything seems to work as expected.  If you set the timeout to zero and check the Prefs on the next line, it will be too soon to see the change.

This is the only method I have found that at least gives the appearance of working cleanly.

I'm not sure if this is how it is supposed to work (by design).  It would be much better if the web interface provided a response (even an empty one).  Then the process would complete like other requests.

One other thing I should mention; I am doing this inside the ValidatePrefs() method.  I don't know if that is causing this issue.  That is a "special" method.

Drop the “u=” The request runs and doesn’t care about the return or lack thereof. This is used successfully in the unsupportedAppStore.

No change.  I just tested it.  I didn't see why it should matter.  A function that returns a value doesn't care if you actually use it.  It is returned anyway.  It just gets popped off the stack and discarded.

I'll check the unsupportedAppStore.

I used:

HTTP.Request(PLEX_PREFS+'fq_file='+fq_file.replace(' ', '%20'), immediate=True, timeout=0.1)

Also, when the wheel stops spinning, I get the sad face, like for a page not found.

MORE INFO:

I checked out the unsupportedAppStore.  Add this to the end of ValidatePrefs OUTSIDE the if block, so it always happens:

 
HTTP.Request('http://localhost:32400/:/plugins/com.plexapp.plugins.unsupportedappstore/prefs/set?adult=False' immediate=True)
 
Then set the preference for Adult plugins to true and see what happens.

This is from RemIdx, and does work:

	opener = urllib2.build_opener(urllib2.HTTPHandler)
	#Enable Index Generation
	request = urllib2.Request('http://127.0.0.1:32400/:/prefs?GenerateIndexFilesDuringAnalysis=1')
	request.get_method = lambda: 'PUT'
	url = opener.open(request)

/T

No change.  I just tested it.  I didn't see why it should matter.  A function that returns a value doesn't care if you actually use it.  It is returned anyway.  It just gets popped off the stack and discarded.

I'll check the unsupportedAppStore.

I used:

HTTP.Request(PLEX_PREFS+'fq_file='+fq_file.replace(' ', '%20'), immediate=True, timeout=0.1)

Also, when the wheel stops spinning, I get the sad face, like for a page not found.

MORE INFO:

I checked out the unsupportedAppStore.  Add this to the end of ValidatePrefs OUTSIDE the if block, so it always happens:

 
 
Then set the preference for Adult plugins to true and see what happens.

The problem with putting that outside an if block is that you setup a never ending loop. The change calls ValidatePrefs() which makes a change which calls ValidatePrefs() until you timeout or the plugin crashes.

If you use this at line 82:

    if Prefs['adult']:
        HTTP.Request('http://localhost:32400/:/plugins/com.plexapp.plugins.unsupportedappstore/prefs/set?adult=False', immediate=True)

Checking the "allow adult" it does successfully allow the change to revert to false. So, it is working as expected for me.

Chris

Oops.  Sorry Chris.  What an embarrassing fail on my part.  It is an infinite loop.

Your code is working fine.

I figured out what I am doing wrong.  I am using:

Thread.AcquireLock('main')

and 

Thread.ReleaseLock('main')
inside
ValidatePrefs()
I did this to prevent MainMenu() (which also uses this thread control) from running when the Prefs were being validated (and possibly changed).  This was to try to prevent a race issue when referencing those values in MainMenu().
However, the Prefs update inside ValidatePrefs() also makes a postback to PMS and invokes ValidatePrefs() again.  Which is blocked by the first call, because it has not finished yet.
It appears that PMS cannot complete the response to the first call while the second call is being blocked.
I verified this in your code.
Add these two threading lines to your code (the first at the beginning and the second at the end, of course) and you will see my problem.
The try block allows the failure to occur gracefully and the process completes as expected.  This is not acceptable.
 
This brings up a concern about updating Prefs inside of ValidatePrefs() due to the callback issue.  If several Prefs are updated sequentially (not all in one call) during the first pass, this could get ugly.
I will be changing my code to avoid this altogether.  I already use a duplicate set for the Prefs to maintain the last set values to detect changes (which I need to know in my case).  Therefore, I should NEVER use the Prefs, only their "last" values.  That will be clean and I won't need the thread control at all; I'll let MainMenu control the updates.
 
I also realized that my thread control effort is not effective, as the changes to the Prefs occur before it enters ValidatePrefs().
I am not consistently thinking of this channel as a website, and not an application.  Big difference there.
 
Thanks for the help!

Yeah, ValidatePrefs() only runs after the Prefs are changed.

Glad I was able to help.

Chris