Skip to content
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

fritzphonebook fails on PhoneBook entries without proper name #79

Open
avierck opened this issue Dec 8, 2020 · 4 comments
Open

fritzphonebook fails on PhoneBook entries without proper name #79

avierck opened this issue Dec 8, 2020 · 4 comments

Comments

@avierck
Copy link

avierck commented Dec 8, 2020

I have no idea why, but ever since updating to Fritz!OS to 07.21 the phonebook on my Fritz!Box 7590 apparently contains an entry for an internal number (**3) that has no username associated with it. While this doesn't even show up on the regular web interface, the iOS Fritz! Fon app is at least able to hand this and shows an entry (null) **3 under the internal numbers.

Now the issue is that fritzphonebook -a is unable to handle such missing names, as seen here:

Traceback (most recent call last):
  File "/Users/myusername/.pyenv/versions/3.8.6/bin/fritzphonebook", line 8, in <module>
    sys.exit(main())
  File "/Users/myusername/.pyenv/versions/3.8.6/lib/python3.8/site-packages/fritzconnection/cli/fritzphonebook.py", line 70, in main
    print_phonebooks(fpb)
  File "/Users/myusername/.pyenv/versions/3.8.6/lib/python3.8/site-packages/fritzconnection/cli/fritzphonebook.py", line 22, in print_phonebooks
    print(f"{name:<30}{', '.join(numbers)}")
TypeError: unsupported format string passed to NoneType.__format__

Which could be solved either by forcing python to interpret name as string type on this line either by changing it to :

        print(f"{name!s:<30}{', '.join(numbers)}")

or

        print(f"{str(name):<30}{', '.join(numbers)}")

which both yield an entry None **3.

Although it would of course be generally more stable if this library would use a more stable type-checking approach, at least by prefacing that line with if isinstance(name, str):


On a related note, has anyone tried using the DeletePhonebookEntryUID method yet? So far I managed to get the raw phonebook data (and thus, I think, got the unique id for my messed-up phonebook entry) via establishing a new FritzConnection and then calling .call_action('X_AVM-DE_OnTel1','GetPhonebook',NewPhonebookId=0) on it, which yields:

   <contact>
   <category>
    0
   </category>
   <person>
    <realname>
    </realname>
   </person>
   <uniqueid>
    14
   </uniqueid>
   <telephony>
    <services>
    </services>
    <!-- numbers:1-->
    <number prio="1" type="intern" vanity="">
     **3
    </number>
    <!-- idx:0 -->
    <!-- ringtoneidx:nil -->
   </telephony>
  </contact>

But I'm unsure how to properly call DeletePhonebookEntryUID and I don't want to mess things up even more.

@avierck
Copy link
Author

avierck commented Dec 10, 2020

Small update:

I've now tried to get more info about that specific contact entry like this:

FB_ADDR = 'redacted'
FB_USER = 'redacted'
FB_PASS = 'redacted'

import requests
from lxml import etree
from fritzconnection import FritzConnection as fco

conn = fco(address=FB_ADDR,user=FB_USER,password=FB_PASS)

def get_info_uid(pb=0,contact_uid=18):
    pbl = conn.call_action('X_AVM-DE_OnTel1','GetPhonebookEntryUID', NewPhonebookId=pb, NewPhonebookEntryUniqueID=contact_uid)
    return pbl['NewPhonebookEntryData']

def get_whole_phonebook(pb=0):
    pbl = conn.call_action('X_AVM-DE_OnTel1','GetPhonebook',NewPhonebookId=pb)
    url = pbl['NewPhonebookURL']

    content = requests.get(url)
    
    xml = content.text.encode('utf-8')
    parser = etree.XMLParser(ns_clean=True, recover=True, encoding='utf-8', remove_comments=True)
    
    root = etree.fromstring(xml, parser=parser)
    tree = etree.ElementTree(root)
    
    for ci, c in enumerate(root.iterfind(".//phonebook/contact")):
        rn = c.findall('.//person/realName')[0].text
        uid = c.findall('.//uniqueid')[0].text
        ph = c.findall('telephony/number')[0].text
        print(c.findall('telephony/number'))
        print(f"[{ci!s:>3}] {uid!s:<3} - {rn!s:<30} {ph!s:<30}")
        
get_whole_phonebook()

Which gives not only names and numbers, but also the s so that one can attempt to retrieve specific information over the GetPhonebookEntryUID service like:

print(get_info_uid(contact_uid=28)) 

Turns out, however, that I can only retrieve data for "normal" phonebook entries, not the internal ones. So I fear that attempting to use DeletePhonebookEntryUID will also fail.

@bufemc
Copy link
Contributor

bufemc commented Dec 19, 2020

Hey @avierck - I also have running the 7.21 on my 7490, but don't have a record for **3. Just **1 for the fax device.
Maybe @kbr has to add something in case a number has no name assigned?

I had also to investigate how to add numbers to the phone book, but could finally manage it - see my code at https://github.com/bufemc/a1fbox - the phonebook class. I guess DeletePhonebookEntryUID should be nearly the same.
Maybe helpful is this resource, too:
https://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/X_contactSCPD.pdf

Another thing - I currently try to get the internal numbers of "Telefonie - Telefoniegeraete".. any ideas?
I will create a new ticket for that.

@kbr
Copy link
Owner

kbr commented Dec 19, 2020

Well, I don't have done any reegineering of undocumented features – or at least I don't know about the documentation – and therefore also don't know what AVM is doing there. However, there is an improved phonebook library module in the pipeline – may be for version 1.5 – better handling to insert or delete phonebook entries. Unfortunately I'm currently short in time, regardless of the lockdown.

@bufemc
Copy link
Contributor

bufemc commented Dec 19, 2020

That would be nice as I just created some kind of XML snippet workaround to add phone numbers, but I guess you could do it the smarter way. Beside of Insert/Delete I would even suggest the full CRUD.. Create, Retrieve, Update, Delete. Why? Scenario: I don't know why, but in my phonebook (whitelist) there are a lot of entries "Name," and I would like to get rid of this nasty "," by updating all the entries. Kleines Wunschkonzert quasi.. Ist denn schon wieder Weihnachten? o;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants