Giter VIP home page Giter VIP logo

Comments (21)

catara avatar catara commented on August 22, 2024

I get:

"capi:logs ladmin$ cat CardDAV
[29-Aug-2012 01:14:53 +0200]: v0.5.1 | carddav_server_id: 1 | Starting CardDAV-Addressbook synchronization
[29-Aug-2012 01:14:53 +0200]: v0.5.1 | carddav_server_id: 1 | Connected to the CardDAV-Server http://capi.ro/addressbooks/users/bogdan/addressbook/
[29-Aug-2012 01:14:53 +0200]: v0.5.1 | carddav_server_id: 1 | CardDAV-Server XML-Response is malformed. Synchronization aborted!
[29-Aug-2012 01:15:07 +0200]: v0.5.1 | carddav_server_id: 1 | Starting CardDAV-Addressbook synchronization
[29-Aug-2012 01:15:08 +0200]: v0.5.1 | carddav_server_id: 1 | Connected to the CardDAV-Server http://capi.ro/addressbooks/users/bogdan/addressbook/
[29-Aug-2012 01:15:08 +0200]: v0.5.1 | carddav_server_id: 1 | CardDAV-Server XML-Response is malformed. Synchronization aborted!"

from roundcube-carddav.

niwrik avatar niwrik commented on August 22, 2024

I am unable to get synchronization working as well.

OSX 10.8 Server
RoundCube 0.8.1
CardDAV 0.5.1

I am able to get the CardDav settings to recgnize my server. However no contacts are synced to the addressbook. When I attempt to sync manually, I get the following error: An error occurred while synchronizing the CardDAV contacts

from roundcube-carddav.

schum avatar schum commented on August 22, 2024

possibly help section 2 in #36

from roundcube-carddav.

mvdbent avatar mvdbent commented on August 22, 2024

I am also able to get the CardDav settings to recgnize my server. and like nlwrik no contacts are synced to the addressbook. When I attempt to sync manually, I get the following error: An error occurred while synchronizing the CardDAV contacts

anybody successful sync with a mountain lion server???

from roundcube-carddav.

niwrik avatar niwrik commented on August 22, 2024

I found a message board where someone had posted a fix for this. I was able to get it running in the end. It involved modifying some code (that I didn't understand) in one of the files. I'll look later and see if I can find it for you.

BK

Sent from my iPhone

On Oct 17, 2012, at 4:00 PM, mvdbent [email protected] wrote:

I am also able to get the CardDav settings to recgnize my server. and like nlwrik no contacts are synced to the addressbook. When I attempt to sync manually, I get the following error: An error occurred while synchronizing the CardDAV contacts

anybody successful sync with a mountain lion server???


Reply to this email directly or view it on GitHub.

from roundcube-carddav.

niwrik avatar niwrik commented on August 22, 2024

@mvdbent schum posted the answer above. I was able to make this work following the link he posted. If you are unable to get it working, I'll look back at my config and reference the changes I made that worked.

from roundcube-carddav.

catara avatar catara commented on August 22, 2024

@niwrik Can you please share your carddav config files, and also the carddav user config (e.g. http://example.com:8080...)

from roundcube-carddav.

beornlake avatar beornlake commented on August 22, 2024

I'm seeing the CardDAV-Server XML-Response is malformed. Synchronization aborted! error as well. My setup is as follows:

  • Mac OS X Server 10.8.2
  • Roundcube Webmail 0.8.4 (hosted on an Ubuntu Linux box)
  • graviox / Roundcube-CardDAV 0.5.1

One note for setup: I had to use http instead of https when configuring the server connection, even though the OS X machine is properly configured to serve https. Trying a secure connection just caused the setup to fail. As soon as I changed to normal http it connected just fine.

I added a self::write_log($e); line to the carddav_addressbook.php file to get a better look at the exception when it gets thrown, and this is what I see:

[25-Jan-2013 15:10:35 -0800]: v0.5.1 |  carddav_server_id: 2 | Starting CardDAV-Addressbook synchronization
[25-Jan-2013 15:10:35 -0800]: v0.5.1 |  carddav_server_id: 2 | Connected to the CardDAV-Server http://SERVER.ADDRESS/addressbooks/users/michael/addressbook/
[25-Jan-2013 15:10:35 -0800]: v0.5.1 |  carddav_server_id: 2 | CardDAV-Server XML-Response is malformed. Synchronization aborted!
[25-Jan-2013 15:10:35 -0800]: v0.5.1 |  carddav_server_id: 2 | exception 'Exception' with message 'String could not be parsed as XML' in /usr/local/etc/roundcube/plugins/carddav/carddav_addressbook.php:402
Stack trace:
#0 /usr/local/etc/roundcube/plugins/carddav/carddav_addressbook.php(402): SimpleXMLElement->__construct('')
#1 /usr/local/etc/roundcube/plugins/carddav/carddav.php(305): carddav_addressbook->carddav_addressbook_sync(Array)
#2 [internal function]: carddav->carddav_addressbook_sync()
#3 /usr/local/etc/roundcube/program/include/rcube_plugin_api.php(316): call_user_func(Array)
#4 /usr/local/etc/roundcube/index.php(279): rcube_plugin_api->exec_action('plugin.carddav-...')
#5 {main}

It looks like carddav_addressbook.php:402 is trying to make a new SimpleXMLElement object by passing an empty string instead of valid XML data.

I tried replacing the PROPFIND line in carddav_backend.php with the three lines from #29, but that has no effect on the problem.

from roundcube-carddav.

bryan977 avatar bryan977 commented on August 22, 2024

Have anyone got this plugin working on Mountain Lion? I've tried the fixes in #29 and #36; however, I still have problems. I still receive the "ardDAV-Server XML-Response is malformed. Synchronization aborted!" error. Thanks so much!

from roundcube-carddav.

niwrik avatar niwrik commented on August 22, 2024

Hello. I stopped using this awhile back and haven't gotten back to it. An OSX update broke roundcude on me (something to do with postgres), so I had to recreate the database using mysql. Prior to that, I was able to sync carddav address book after making the changes to carddav_backend.php. Sorry, but I don't recall the exact lines of code I change (per instructions in the message board). If it helps, here's the code from the file that worked for me:

set_auth('username', 'password'); - echo $carddav->get(); * * - Simple vCard query - ------------------ - $carddav = new carddav_backend('https://davical.example.com/user/contacts/'); - $carddav->set_auth('username', 'password'); - echo $carddav->get_vcard('0126FFB4-2EB74D0A-302EA17F'); * * - XML vCard query - ------------------ - $carddav = new carddav_backend('https://davical.example.com/user/contacts/'); - $carddav->set_auth('username', 'password'); - echo $carddav->get_xml_vcard('0126FFB4-2EB74D0A-302EA17F'); * * - Check CardDAV server connection - ------------------------------- - $carddav = new carddav_backend('https://davical.example.com/user/contacts/'); - $carddav->set_auth('username', 'password'); - var_dump($carddav->check_connection()); * * - CardDAV delete query - -------------------- - $carddav = new carddav_backend('https://davical.example.com/user/contacts/'); - $carddav->set_auth('username', 'password'); - $carddav->delete('0126FFB4-2EB74D0A-302EA17F'); * * - CardDAV add query - -------------------- - $vcard = 'BEGIN:VCARD - VERSION:3.0 - UID:1f5ea45f-b28a-4b96-25as-ed4f10edf57b - FN:Christian Putzke - N:Christian;Putzke;;; - EMAIL;TYPE=OTHER:[email protected] - END:VCARD'; * - $carddav = new carddav_backend('https://davical.example.com/user/contacts/'); - $carddav->set_auth('username', 'password'); - $vcard_id = $carddav->add($vcard); * * - CardDAV update query - -------------------- - $vcard = 'BEGIN:VCARD - VERSION:3.0 - UID:1f5ea45f-b28a-4b96-25as-ed4f10edf57b - FN:Christian Putzke - N:Christian;Putzke;;; - EMAIL;TYPE=OTHER:[email protected] - END:VCARD'; * - $carddav = new carddav_backend('https://davical.example.com/user/contacts/'); - $carddav->set_auth('username', 'password'); - $carddav->update($vcard, '0126FFB4-2EB74D0A-302EA17F'); * * - CardDAV server list - ------------------- - DAViCal: https://example.com/{resource|principal|username}/{collection}/ - Apple Addressbook Server: https://example.com/addressbooks/users/{resource|principal|username}/{collection}/ - memotoo: https://sync.memotoo.com/cardDAV/ - SabreDAV: https://example.com/addressbooks/{resource|principal|username}/{collection}/ - ownCloud: https://example.com/apps/contacts/carddav.php/addressbooks/{resource|principal|username}/{collection}/ - SOGo: http://sogo-demo.inverse.ca/SOGo/dav/{resource|principal|username}/Contacts/{collection}/ * * - @author Christian Putzke [email protected] - @copyright Christian Putzke @ Graviox Studios - @link http://www.graviox.de/ - @link https://twitter.com/graviox/ - @SInCE 20.07.2011 - @Version 0.5.1 - @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * */ class carddav_backend { /** \* CardDAV PHP Version * \* @constant string */ const VERSION = '0.5.1'; ``` /** * User agent displayed in http requests * * @constant string */ const USERAGENT = 'CardDAV PHP/'; /** * CardDAV server url * * @var string */ private $url = null; /** * CardDAV server url_parts * * @var array */ private $url_parts = null; /** * Authentication string * * @var string */ private $auth = null; /** * Authentication: username * * @var string */ private $username = null; /** * Authentication: password * * @var string */ private $password = null; /** * Characters used for vCard id generation * * @var array */ private $vcard_id_chars = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'A', 'B', 'C', 'D', 'E', 'F'); /** * CardDAV server connection (curl handle) * * @var resource */ private $curl; /** * Constructor * Sets the CardDAV server url * * @param string $url CardDAV server url * @return void */ public function __construct($url = null) { if ($url !== null) { $this->set_url($url); } } /** * Sets the CardDAV server url * * @param string $url CardDAV server url * @return void */ public function set_url($url) { $this->url = $url; if (substr($this->url, -1, 1) !== '/') { $this->url = $this->url . '/'; } $this->url_parts = parse_url($this->url); } /** * Sets authentication string * * @param string $username CardDAV server username * @param string $password CardDAV server password * @return void */ public function set_auth($username, $password) { $this->username = $username; $this->password = $password; $this->auth = $username . ':' . $password; } /** * Gets propfind XML response from the CardDAV server * * @param boolean $include_vcards vCards include vCards in the response (simplified only) * @param boolean $raw Get response raw or simplified * @return string Raw or simplified XML response */ public function get($include_vcards = true, $raw = false) { /** $response = $this->query($this->url, 'PROPFIND'); */ $content = '
                <D:sync-collection xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:carddav">
                <D:sync-token></D:sync-token>
                <D:sync-level>1</D:sync-level>
                <D:prop><D:getcontenttype/><D:getetag/><D:allprop/>
                <C:address-data><C:allprop/></C:address-data></D:prop>
                <C:filter/></D:sync-collection>';
$content_type = 'application/xml';
$response = $this->query($this->url, 'REPORT', $content, $content_type);



if ($response === false || $raw === true)
{
    return $response;
}
else
{
    return $this->simplify($response, $include_vcards);
}

}

/**

  • Gets a clean vCard from the CardDAV server
  • @param string $vcard_id vCard id on the CardDAV server
  • @return string vCard (text/vcard)
    */
    public function get_vcard($vcard_id)
    {
    $vcard_id = str_replace('.vcf', null, $vcard_id);
    return $this->query($this->url . $vcard_id . '.vcf', 'GET');
    }

/**

  • Gets a vCard + XML from the CardDAV Server

  • @param string $vcard_id vCard id on the CardDAV Server

  • @param boolean $raw Get response raw or simplified

  • @return string Raw or simplified vCard (text/xml)
    */
    public function get_xml_vcard($vcard_id, $raw = false)
    {
    $vcard_id = str_replace('.vcf', null, $vcard_id);

    $xml = new XMLWriter();
    $xml->openMemory();
    $xml->setIndent(4);
    $xml->startDocument('1.0', 'utf-8');
    $xml->startElement('C:addressbook-multiget');
    $xml->writeAttribute('xmlns:D', 'DAV:');
    $xml->writeAttribute('xmlns:C', 'urn:ietf:params:xml:ns:carddav');
    $xml->startElement('D:prop');
    $xml->writeElement('D:getetag');
    $xml->writeElement('D:getlastmodified');
    $xml->endElement();
    $xml->writeElement('D:href', $this->url_parts['path'] . $vcard_id . '.vcf');
    $xml->endElement();
    $xml->endDocument();

    $response = $this->query($this->url, 'REPORT', $xml->outputMemory(), 'text/xml');

    if ($raw === true || $response === false)
    {
    return $response;
    }
    else
    {
    return $this->simplify($response, true);
    }
    }

/**

  • Checks if the CardDAV server is reachable
  • @return boolean
    */
    public function check_connection()
    {
    return $this->query($this->url, 'OPTIONS', null, null, true);
    }

/**

  • Cleans the vCard

  • @param string $vcard vCard

  • @return string $vcard vCard
    */
    private function clean_vcard($vcard)
    {
    $vcard = str_replace("\t", null, $vcard);

    return $vcard;
    }

/**

  • Deletes an entry from the CardDAV server
  • @param string $vcard_id vCard id on the CardDAV server
  • @return boolean
    */
    public function delete($vcard_id)
    {
    return $this->query($this->url . $vcard_id . '.vcf', 'DELETE', null, null, true);
    }

/**

  • Adds an entry to the CardDAV server

  • @param string $vcard vCard

  • @return string The new vCard id
    */
    public function add($vcard)
    {
    $vcard_id = $this->generate_vcard_id();
    $vcard = $this->clean_vcard($vcard);

    if ($this->query($this->url . $vcard_id . '.vcf', 'PUT', $vcard, 'text/vcard', true) === true)
    {
    return $vcard_id;
    }
    else
    {
    return false;
    }
    }

/**

  • Updates an entry to the CardDAV server

  • @param string $vcard vCard

  • @param string $vcard_id vCard id on the CardDAV server

  • @return boolean
    */
    public function update($vcard, $vcard_id)
    {
    $vcard_id = str_replace('.vcf', null, $vcard_id);
    $vcard = $this->clean_vcard($vcard);

    return $this->query($this->url . $vcard_id . '.vcf', 'PUT', $vcard, 'text/vcard', true);
    }

/**

  • Simplify CardDAV XML response

  • @param string $response CardDAV XML response

  • @param boolean $include_vcards Include vCards or not

  • @return string Simplified CardDAV XML response
    */
    private function simplify($response, $include_vcards = true)
    {
    $response = $this->clean_response($response);
    $xml = new SimpleXMLElement($response);

    $simplified_xml = new XMLWriter();
    $simplified_xml->openMemory();
    $simplified_xml->setIndent(4);

    $simplified_xml->startDocument('1.0', 'utf-8');
    $simplified_xml->startElement('response');

         foreach ($xml->response as $response)
         {
             if (preg_match('/vcard/', $response->propstat->prop->getcontenttype) || preg_match('/vcf/', $response->href))
             {
                 $id = basename($response->href);
                 $id = str_replace('.vcf', null, $id);
    
                 if (!empty($id))
                 {
                     $simplified_xml->startElement('element');
                         $simplified_xml->writeElement('id', $id);
                         $simplified_xml->writeElement('etag', str_replace('"', null, $response->propstat->prop->getetag));
                         $simplified_xml->writeElement('last_modified', $response->propstat->prop->getlastmodified);
    
                         if ($include_vcards === true)
                         {
                             $simplified_xml->writeElement('vcard', $this->get_vcard($id));
                         }
                     $simplified_xml->endElement();
                 }
             }
             else if (preg_match('/unix-directory/', $response->propstat->prop->getcontenttype))
             {
                 if (isset($response->propstat->prop->href))
                 {
                     $href = $response->propstat->prop->href;
                 }
                 else if (isset($response->href))
                 {
                     $href = $response->href;
                 }
                 else
                 {
                     $href = null;
                 }
    
                 $url = str_replace($this->url_parts['path'], null, $this->url) . $href;
                 $simplified_xml->startElement('addressbook_element');
                     $simplified_xml->writeElement('display_name', $response->propstat->prop->displayname);
                     $simplified_xml->writeElement('url', $url);
                     $simplified_xml->writeElement('last_modified', $response->propstat->prop->getlastmodified);
                 $simplified_xml->endElement();
             }
         }
    
     $simplified_xml->endElement();
    

    $simplified_xml->endDocument();

    return $simplified_xml->outputMemory();
    }

/**

  • Cleans CardDAV XML response

  • @param string $response CardDAV XML response

  • @return string $response Cleaned CardDAV XML response
    */
    private function clean_response($response)
    {
    $response = utf8_encode($response);
    $response = str_replace('D:', null, $response);
    $response = str_replace('d:', null, $response);
    $response = str_replace('C:', null, $response);
    $response = str_replace('c:', null, $response);

    return $response;
    }

/**

  • Curl initialization

  • @return void
    */
    public function curl_init()
    {
    if (empty($this->curl))
    {
    $this->curl = curl_init();
    curl_setopt($this->curl, CURLOPT_HEADER, false);
    curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($this->curl, CURLOPT_USERAGENT, self::USERAGENT.self::VERSION);

     if ($this->auth !== null)
     {
         curl_setopt($this->curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
         curl_setopt($this->curl, CURLOPT_USERPWD, $this->auth);
     }
    

    }
    }

/**

  • Quries the CardDAV server via curl and returns the response

  • @param string $url CardDAV server URL

  • @param string $method HTTP-Method like (OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, COPY, MOVE)

  • @param string $content Content for CardDAV queries

  • @param string $content_type Set content type

  • @param boolean $return_boolean Return just a boolean

  • @return string CardDAV XML response
    */
    private function query($url, $method, $content = null, $content_type = null, $return_boolean = false)
    {
    $this->curl_init();

    curl_setopt($this->curl, CURLOPT_URL, $url);
    curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $method);

    if ($content !== null)
    {
    curl_setopt($this->curl, CURLOPT_POST, true);
    curl_setopt($this->curl, CURLOPT_POSTFIELDS, $content);
    }
    else
    {
    curl_setopt($this->curl, CURLOPT_POST, false);
    curl_setopt($this->curl, CURLOPT_POSTFIELDS, null);
    }

    if ($content_type !== null)
    {
    curl_setopt($this->curl, CURLOPT_HTTPHEADER, array('Content-type: '.$content_type));
    }
    else
    {
    curl_setopt($this->curl, CURLOPT_HTTPHEADER, array());
    }

    $response = curl_exec($this->curl);
    $http_code = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);

    if (in_array($http_code, array(200, 207)))
    {
    return ($return_boolean === true ? true : $response);
    }
    else if ($return_boolean === true && in_array($http_code, array(201, 204)))
    {
    return true;
    }
    else
    {
    return false;
    }
    }

/**

  • Returns a valid and unused vCard id

  • @return string Valid vCard id
    */
    private function generate_vcard_id()
    {
    $id = null;

    for ($number = 0; $number <= 25; $number ++)
    {
    if ($number == 8 || $number == 17)
    {
    $id .= '-';
    }
    else
    {
    $id .= $this->vcard_id_chars[mt_rand(0, (count($this->vcard_id_chars) - 1))];
    }
    }

    $carddav = new carddav_backend($this->url);
    $carddav->set_auth($this->username, $this->password);

    if ($carddav->query($this->url . $id . '.vcf', 'GET', null, null, true))
    {
    return $this->generate_vcard_id();
    }
    else
    {
    return $id;
    }
    }

/**

  • Destructor
  • Close curl connection if it's open
  • @return void
    */
    public function __destruct()
    {
    if (!empty($this->curl))
    {
    curl_close($this->curl);
    }
    }

}

On Feb 1, 2013, at 10:33 AM, bryan977 [email protected] wrote:

> Have anyone got this plugin working on Mountain Lion? I've tried the fixes in #29 and #36; however, I still have problems. I still receive the "ardDAV-Server XML-Response is malformed. Synchronization aborted!" error. Thanks so much!
> 
> �
> Reply to this email directly or view it on GitHub.

from roundcube-carddav.

bryan977 avatar bryan977 commented on August 22, 2024

Thank you niwrik! I'll give this a try. I've been using Kerio Connect for the last several years, but, was considering going the "free" route and using the butil-in services to ML. This is just my home personal email server for family and friends, so, I can be pretty nimble. Thanks so much!

from roundcube-carddav.

benjennings avatar benjennings commented on August 22, 2024

has anyone managed to get CardDAV working with Mountain Lion Server (10.8.2) and RoundCube 0.8.5? I can add the server but then on sync it just says:

"an error occurred while synchronizing the CardDave contacts"

any pointers?

from roundcube-carddav.

bryan977 avatar bryan977 commented on August 22, 2024

I have not. I am hoping, at some point, someone smarter than I can make it work and share. Or, the connector is updated to work with ML Server.

from roundcube-carddav.

benjennings avatar benjennings commented on August 22, 2024

hey @bryan977 thanks for getting back - glad it's not just me! so any genius out there with a solution? :)

from roundcube-carddav.

hscissors avatar hscissors commented on August 22, 2024

Have you tried using another CardDav service like Radicale? There is a repo on Github. I haven't used it with Mountain Lion, but its a pretty lightweight python application that works behind Apache or on its on. I have it working with RoundCube.

from roundcube-carddav.

benjennings avatar benjennings commented on August 22, 2024

@hscissors thanks for the pointer - but it would be great if it were possible to get CardDAV working with a default Mountain Lion Server install :)

from roundcube-carddav.

niwrik avatar niwrik commented on August 22, 2024

I had a request this morning to get carddav working on roundcube at the office. I hadn't gotten back to this since my earlier post, as I'd never bothered to restore the configuration following my move from postgres to mysql for the roundcube db. Again, I ran into the same problems as above. Luckily, I had made a backup of the working plugin folder, and restored it to my current config. Confirmed working on 10.8.2 - I have no idea which files were modified to make it work, but I can post the folder in .zip format somewhere if anyone wants to try it out in their deployment.

from roundcube-carddav.

bpwats avatar bpwats commented on August 22, 2024

I would be interested in that.

from roundcube-carddav.

niwrik avatar niwrik commented on August 22, 2024

@bpwats Send me a message and I'll send you a link. My public e-mail address is now published.

from roundcube-carddav.

niwrik avatar niwrik commented on August 22, 2024

Hello Everyone. I have this running on OSX 10.8.2 Server 2.2.1 with RC 0.8.2. I found the solution here: #36 (about half-way down the page)

In carddav_backend.php replace the following line:

$response = $this->query($this->url, 'PROPFIND');

with this:
screen shot 2013-06-26 at 2 27 04 pm

from roundcube-carddav.

sylvestrerd avatar sylvestrerd commented on August 22, 2024

Hello
You can modify in the carddav_backend.php the auth type.
I had the same problem of XML because the response is empty.
change this line
curl_setopt($this->curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
by
curl_setopt($this->curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
the url : https://xxxxx:8843/addressbooks/users/[username]/addressbook/
For me it's working.
Is it possible to add a DropDownList to configure the server like calendar.

from roundcube-carddav.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.