GNOME Bugzilla – Bug 520699
Support Google Contacts via GData
Last modified: 2018-07-01 17:11:59 UTC
"The Google Contacts Data API allows client applications to view and update Contacts content in the form of Google Data API feeds. Your client application can request a list of a user's contacts, edit or delete content in an existing contact, and query the content in an existing contact." http://code.google.com/apis/contacts/
Oooooooh thats new. Are you volunteering :-) Any takers?
Don't curse it. I don't fancy mapping GData to VCard, but i'm going to at least get GData to file and back working, and see what happens from there.. Atm it won't let me log in though >: (
Created attachment 106674 [details] [review] Login and get a list of all contacts Figured out the magic to login \o/ This gets us a list of UIDs. Each UID will need passing to (i think) self.service.Get(). This will return the GData XML representing a contact. I will pack this into a new object type ("contact/gdata") and for starters implement contact/gdata <-> file conversions. We should be able to just call self.service.Delete() on the same UID too, though haven't tried this. Need to investigate what is done for Update - all i've seen (so far) are comments discouraging Delete/Add cycles. Note: There is no GUI yet! I manually called set_username and set_password in __init__ to configure this on my box.
Created attachment 106684 [details] [review] Able to Get() XML for each contact and allegedly Delete() too Gets the XML for each contact and stores it in a GContact object. For now it logs the XML too. TODO (in order of priority): * Convert to file and to vcard * GUI! * Implement add / update * Convert to GContact from file and vcard * Make use of the "changes since" powers of the API
Created attachment 106723 [details] [review] Config GUI and dumping XML to file Can now sync contacts to file, but not to VCard stuff yet. Going to make this two way next..
Looks good so far! When you do the VCard stuff, I would recommend just switching Google to use our Contact data type. Its the same amount of code you would have to write, but it lives in the Contact class instead of the Converter. Its one less converter to maintain, and its easier to test
Any progress? Id like to get this in for an upcoming release
I got tied up at work. Gonna be flat out this month, so i dunno how capable i'm gonna be. If anyone wants to help out i'd appreciate it.
Sure, I'll grab hold and take a swing. Or some other combination of sports metaphors. ;)
Any progress here guys?
*** Bug 524738 has been marked as a duplicate of this bug. ***
(In reply to comment #6) > Looks good so far! > > When you do the VCard stuff, I would recommend just switching Google to use our > Contact data type. Its the same amount of code you would have to write, but it > lives in the Contact class instead of the Converter. Its one less converter to > maintain, and its easier to test > Ok, so I finally got around to working on this more and after following the code and handling some odd exceptions being spewed with my contacts (bad characters mostly). I'm currently grappling with a limited knowledge of vobject and the vCard format. Given its general uglyness to work with, is there a strong reason (beyond eds being the only real contacts backend initially, and it working well with vCard) that we use vCard for our Contacts as opposed to doing something a little more pythonic and awesome like a dict? To put my thoughts in context, I wanted to start providing sync logic for social networks to address books (ie. my friend updates his e-mail on facebook, and I automatically get it added to my address book). Since that will entail a lot more users of Contact than before, and a lot of gruntwork to translate pretty objects, collections and json into ugly vCard, I thought I would at least ask if it was a choice of convenience or design. It just seems like translating from vCard->Tuple/Object for the eds backend, once is a better place to have such messy parsing logic. My $0.02, lemme know.
I hate it too, i'd go so far as to say i'd probably have gotten further on this if it had not been for my distaste for the vObject API. Inititally we used vcard because it was a standard and most things seemed to support it. Right now though we have: Things not using vcard: SynCE -> speaks AirSync XML or OpenSync XML Google Calendars -> speaks Google XML Facebook -> Will involve ugly screen scraping, certainly not vcard Gammu -> Pretty sure its not vcard, anyway.. Things using vcard Evolution iPod Anything accepting a File (VCard is a sensible "to disk" output) While i'd love an easy to use object for working with contact data, looking at the opensync schemas there is a lot of data to deal with: http://svn.opensync.org/trunk/misc/schemas If your willing to make something cool and easy to work with, i'd +1 it. And i'd buy you beer..
Yeah I am pretty pragmatic about the whole thing really. IIRC Jc2k got some way through a pythonic xml backed implementation, using xml-object. However either I was too impatient, or it was not completed in time so I went with vObject. For the sake of being able to experiment with eds. If you can come up with some python-god-magic way of starting with a (opensync) schema and having it present as a python object, with the ability to serialze to xml according to said shema then I would go furthur than Jc2k and probbably buy you a whisky. On the other hand we can do this atop vObject, its just a matter of biting the bullet and actually doing the hard stuff. Heck its just reading the vCard spec and coming up with a list of the top 20 properties, then doing python magic and present them as properties, or as a dict. Its up to the implementor really. Personally I would rather do the latter, but thats just because I think those things not using vCard are not going to be using whatever we decide to implement anyway. Writing glue code is inevitable, it just needs someone to write it
I don't know if I ever implemented anything directly in conduit, but I was experimenting "out of tree" with a reimplementation of some of the (unmaintained) sql-object like kits for working with XML. They are pretty cool and worth a look, but they aren't magical and we are still going to end up with crufty code in some cases... So +1 what nzjrs said. And i'll make it a double whisky.
Created attachment 108437 [details] [review] Inital vCard stuff Alright, well for now I'll just succumb to fate and do the vCard thang. The main problem is how my contacts are actually getting to me from Google, I guess I imported my contacts a long time ago, so _none_ of their information comes structured, I get the name of the contact and a text field with: Name: Mobile Phone: Tel: etc. (but nothing consistent) So while I get that fixed heres the start. However, if we are ok adding lxml as a conduit dep, it has some really powerful tools for this 'magic xml object' stuff ;)
(In reply to comment #16) > Created an attachment (id=108437) [edit] > Inital vCard stuff > > Alright, well for now I'll just succumb to fate and do the vCard thang. The > main problem is how my contacts are actually getting to me from Google, I guess > I imported my contacts a long time ago, so _none_ of their information comes > structured, I get the name of the contact and a text field with: > Name: > Mobile Phone: > Tel: > etc. (but nothing consistent) Thats surprising, do you think its just a bug/inconsistency in how your contacts were imported. I mean looking at http://code.google.com/apis/contacts/developers_guide_protocol.html it looks like you are meant to get back structured xml at least. > > So while I get that fixed heres the start. However, if we are ok adding lxml as > a conduit dep, it has some really powerful tools for this 'magic xml object' > stuff ;) I guess this dep will be OK (not ideal because it not pure python). However I would still need to decide once I saw the implementation, and how the other dataproviders interact with it. Also, one thing I just found is according to http://groups.google.com/group/google-contacts-api/browse_thread/thread/ed7527d8c7f9a540/e4f67f47c15a260c#e4f67f47c15a260c multiple contacts can not have the same email. Bear this in mind for the PUT case - it means that you may as well use the contacts email for the UID
(In reply to comment #17) > (In reply to comment #16) > > Created an attachment (id=108437) [edit] > > Inital vCard stuff > > > > Alright, well for now I'll just succumb to fate and do the vCard thang. The > > main problem is how my contacts are actually getting to me from Google, I guess > > I imported my contacts a long time ago, so _none_ of their information comes > > structured, I get the name of the contact and a text field with: > > Name: > > Mobile Phone: > > Tel: > > etc. (but nothing consistent) > > Thats surprising, do you think its just a bug/inconsistency in how your > contacts were imported. I mean looking at > http://code.google.com/apis/contacts/developers_guide_protocol.html it looks > like you are meant to get back structured xml at least. I'm thinking its just my contacts, in gmail they all just have information in the 'Notes' field. :( > > > > > So while I get that fixed heres the start. However, if we are ok adding lxml as > > a conduit dep, it has some really powerful tools for this 'magic xml object' > > stuff ;) > > I guess this dep will be OK (not ideal because it not pure python). However I > would still need to decide once I saw the implementation, and how the other > dataproviders interact with it. > Fair enough ;) But before I get all off on some nerdtastic tangent I'll try to wrap up this contacts stuff. > Also, one thing I just found is according to > http://groups.google.com/group/google-contacts-api/browse_thread/thread/ed7527d8c7f9a540/e4f67f47c15a260c#e4f67f47c15a260c > multiple contacts can not have the same email. Bear this in mind for the PUT > case - it means that you may as well use the contacts email for the UID > Awesome! something uniform!
Created attachment 108972 [details] [review] Better vCard parser Do vCard more right, still needs more properties handled correctly, has some massive and ugly datetime problems, a hacky workaround in place now. In short, the source is alright, need to get working on a sink. Something I'm noticing, we aren't very smart in situations where many of the same contacts already exist etc. Once we do the initial sync, its in out db and its ok, but we should consider doing some better handling of this. ie Contact1: Kevin Kubasik kevin@kubasik.net Contact2 Kevin Kubasik kevin@kubasik.net admin@kubasik.net We should do some sort of merge between the two. I know this hinges in a lot of ways on changing the current Contact datatype, but just fielding the thought.
I committed your patch with some modifications. Its a good start. I would like to see suitable setters added to Contact datatype once you are more sure of what you need. I gave some examples in the code on how this would look. For two way support see http://www.conduit-project.org/wiki/WritingADataProvider/GeneralPutInstructions for the general approach in how to structure put Re merging: I will call merge() (not yet implemented in any datatypes) in the default conflict handler when a conflict is raised. Its a per datatype problem. I have some example code doing this, but I need a use case for finishing it. Evolution to google would be that use case, so I would really like to see this work go well! It would then give me the motivation to finish merge Good work! Run the next few patches past me, but I am happy to let you start committing stuff soon.
Any updates?
*** Bug 528998 has been marked as a duplicate of this bug. ***
(In reply to comment #20) > I committed your patch with some modifications. Its a good start. I would like > to see suitable setters added to Contact datatype once you are more sure of > what you need. I gave some examples in the code on how this would look. Cool, def something I'd like to see as well, not very easy to do against a vcard backend... so I'll look into that. > > For two way support see > http://www.conduit-project.org/wiki/WritingADataProvider/GeneralPutInstructions > for the general approach in how to structure put Thanks! > > Re merging: I will call merge() (not yet implemented in any datatypes) in the > default conflict handler when a conflict is raised. Its a per datatype problem. > > I have some example code doing this, but I need a use case for finishing it. > Evolution to google would be that use case, so I would really like to see this > work go well! It would then give me the motivation to finish merge > I dunno if I'm the best to prototype this solution, but once I get put() working, I can look at it. ;) > Good work! > > Run the next few patches past me, but I am happy to let you start committing > stuff soon. Cool, will do. :) >
Has any progress been made on this? It's looking great!
Sorry, school/work have been swamping me, its really just put() that needs writing. It should be straightforward enough, I just won't have the time for a while.
I just went in and rewrote all of this to use the newer, included, 1.0.12 version of python-gdata (which features improved support for google contacts service). This still needs work in converting all the gdata attributes, detecting duplicate contacts with the same email address, and general testing, but it is a start
I'was just going by and fell into reading your discussion. Just wanted to point out, just in case, that no two contacts may have same e-mail address in Gmail, but there may still be one or more contacts without e-mail address. So it is UNIQUE but may be NULL. Sorry if it was already obvious to you and this comment is uneeded.
The following code corrects the "only 25 contacts" issue... Replace the definition of _get_all_contacts in ContactsTwoWay class by: def _get_all_contacts(self): entries=[] next_uri=None while True: if next_uri: feed = self.service.GetContactsFeed(next_uri) else: feed = self.service.GetContactsFeed() entries.extend(feed.entry) linknext=[link.href for link in feed.link if link.rel=='next'] if not linknext: break else: next_uri=linknext[0] return [str(contact.id.text) for contact in entries] Some other modifications: * support for phones, addresses, * caching of entries (notice that _get_all_contacts fetches the whole entries, not only the UIDs) are on the way... But I will need to modify some other modules, for instance conduit.datatypes.Contact ... How should I do it? I mean, can I post patches on the code?, or it is better to implement, say, conduit.datatypes.MyContact with the modifications...
Conduit is not under active development anymore, has not seen code changes for eight years, and saw its last tarball release in 2010. Its codebase has been archived: https://gitlab.gnome.org/Archive/conduit/commits/master Closing this report as WONTFIX as part of Bugzilla Housekeeping to reflect reality. Please feel free to reopen this ticket (or rather transfer the project to GNOME Gitlab, as GNOME Bugzilla is deprecated) if anyone takes the responsibility for active development again.