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

Initial commit to expose face recognition information through DAV properties #549

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

matiasdelellis
Copy link
Owner

@matiasdelellis matiasdelellis commented Dec 21, 2021

See examples:

Faces of image:

curl -u user:password https://example.com/remote.php/dav/files/user/Photos/image6.jpg -X PROPFIND --data '<?xml version="1.0" encoding="UTF-8"?>
<d:propfind
    xmlns:d="DAV:"
    xmlns:fr="http://github.com/matiasdelellis/facerecognition/ns">
    <d:prop>
        <fr:faces/>
    </d:prop>
</d:propfind>'

Response:

<?xml version="1.0"?>
<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:oc="http://owncloud.org/ns" xmlns:fr="http://github.com/matiasdelellis/facerecognition/ns" xmlns:nc="http://nextcloud.org/ns">
  <d:response>
    <d:href>/remote.php/dav/files/user/Photos/image6.jpg</d:href>
    <d:propstat>
      <d:prop>
        <fr:faces>
          <fr:person>
            <fr:id>304033</fr:id>
            <fr:name>Bernadette Rostenkowski</fr:name>
            <fr:top>736</fr:top>
            <fr:left>1736</fr:left>
            <fr:width>88</fr:width>
            <fr:height>87</fr:height>
          </fr:person>
          <fr:person>
            <fr:id>300625</fr:id>
            <fr:top>700</fr:top>
            <fr:left>1224</fr:left>
            <fr:width>87</fr:width>
            <fr:height>87</fr:height>
          </fr:person>
          <fr:person>
            <fr:id>300626</fr:id>
            <fr:top>320</fr:top>
            <fr:left>737</fr:left>
            <fr:width>104</fr:width>
            <fr:height>105</fr:height>
          </fr:person>
        </fr:faces>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
</d:multistatus>

Faces of images within an folder:

curl -u user:password https://example.com/remote.php/dav/files/user/Photos/The%20Big%20Bang%20Theory/Emmy%20Awards/ -X PROPFIND --data '<?xml version="1.0" encoding="UTF-8"?>
<d:propfind
    xmlns:d="DAV:"
    xmlns:fr="http://github.com/matiasdelellis/facerecognition/ns">
    <d:prop>
        <fr:faces/>
    </d:prop>
</d:propfind>'

Response:

<?xml version="1.0"?>
<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:oc="http://owncloud.org/ns" xmlns:fr="http://github.com/matiasdelellis/facerecognition/ns" xmlns:nc="http://nextcloud.org/ns">
  <d:response>
    <d:href>/remote.php/dav/files/user/Photos/The%20Big%20Bang%20Theory/Emmy%20Awards/</d:href>
    <d:propstat>
      <d:prop>
        <fr:faces>0</fr:faces>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
  <d:response>
    <d:href>/remote.php/dav/files/user/Photos/The%20Big%20Bang%20Theory/Emmy%20Awards/100_138375514.jpg</d:href>
    <d:propstat>
      <d:prop>
        <fr:faces>
          <fr:person>
            <fr:id>294082</fr:id>
            <fr:name>Sheldon Cooper</fr:name>
            <fr:top>302</fr:top>
            <fr:left>785</fr:left>
            <fr:width>233</fr:width>
            <fr:height>233</fr:height>
          </fr:person>
        </fr:faces>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
  <d:response>
    <d:href>/remote.php/dav/files/user/Photos/The%20Big%20Bang%20Theory/Emmy%20Awards/100_138379368.jpg</d:href>
    <d:propstat>
      <d:prop>
        <fr:faces>
          <fr:person>
            <fr:id>302773</fr:id>
            <fr:top>180</fr:top>
            <fr:left>1911</fr:left>
            <fr:width>96</fr:width>
            <fr:height>94</fr:height>
          </fr:person>
          <fr:person>
            <fr:id>302774</fr:id>
            <fr:top>1361</fr:top>
            <fr:left>124</fr:left>
            <fr:width>80</fr:width>
            <fr:height>79</fr:height>
          </fr:person>
          <fr:person>
            <fr:id>294082</fr:id>
            <fr:name>Sheldon Cooper</fr:name>
            <fr:top>193</fr:top>
            <fr:left>395</fr:left>
            <fr:width>138</fr:width>
            <fr:height>137</fr:height>
          </fr:person>
          <fr:person>
            <fr:id>302775</fr:id>
            <fr:top>1336</fr:top>
            <fr:left>245</fr:left>
            <fr:width>79</fr:width>
            <fr:height>80</fr:height>
          </fr:person>
          <fr:person>
            <fr:id>302776</fr:id>
            <fr:top>1039</fr:top>
            <fr:left>140</fr:left>
            <fr:width>80</fr:width>
            <fr:height>80</fr:height>
          </fr:person>
        </fr:faces>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
  <d:response>
    <d:href>/remote.php/dav/files/user/Photos/The%20Big%20Bang%20Theory/Emmy%20Awards/100_138379371.jpg</d:href>
    <d:propstat>
      <d:prop>
        <fr:faces>
          <fr:person>
            <fr:id>302937</fr:id>
            <fr:top>528</fr:top>
            <fr:left>798</fr:left>
            <fr:width>109</fr:width>
            <fr:height>109</fr:height>
          </fr:person>
          <fr:person>
            <fr:id>302938</fr:id>
            <fr:top>682</fr:top>
            <fr:left>1325</fr:left>
            <fr:width>91</fr:width>
            <fr:height>90</fr:height>
          </fr:person>
          <fr:person>
            <fr:id>302939</fr:id>
            <fr:top>1754</fr:top>
            <fr:left>88</fr:left>
            <fr:width>75</fr:width>
            <fr:height>76</fr:height>
          </fr:person>
        </fr:faces>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
  <d:response>
    <d:href>/remote.php/dav/files/user/Photos/The%20Big%20Bang%20Theory/Emmy%20Awards/100_138381777.jpg</d:href>
    <d:propstat>
      <d:prop>
        <fr:faces>
          <fr:person>
            <fr:id>302940</fr:id>
            <fr:top>251</fr:top>
            <fr:left>1140</fr:left>
            <fr:width>274</fr:width>
            <fr:height>273</fr:height>
          </fr:person>
        </fr:faces>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
  <d:response>
    <d:href>/remote.php/dav/files/user/Photos/The%20Big%20Bang%20Theory/Emmy%20Awards/100_140761529.jpg</d:href>
    <d:propstat>
      <d:prop>
        <fr:faces>
          <fr:person>
            <fr:id>304066</fr:id>
            <fr:top>264</fr:top>
            <fr:left>500</fr:left>
            <fr:width>333</fr:width>
            <fr:height>333</fr:height>
          </fr:person>
          <fr:person>
            <fr:id>301476</fr:id>
            <fr:top>297</fr:top>
            <fr:left>1161</fr:left>
            <fr:width>400</fr:width>
            <fr:height>400</fr:height>
          </fr:person>
          <fr:person>
            <fr:id>301477</fr:id>
            <fr:top>406</fr:top>
            <fr:left>1231</fr:left>
            <fr:width>230</fr:width>
            <fr:height>230</fr:height>
          </fr:person>
        </fr:faces>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
</d:multistatus>

…perties

Until now, just implemented get the persons and faces within an image..

curl -u user:password 'https://example.com/remote.php/dav/files/user/Photos/someimage.jpg' -X PROPFIND --data '<?xml version="1.0" encoding="UTF-8"?>
<d:propfind xmlns:d="DAV:" xmlns:fr="http://github.com/matiasdelellis/facerecognition/ns">
  <d:prop>
    <fr:persons/>
  </d:prop>
</d:propfind>'
Well, basically it is an almost exact copy of FilesReportPlugin.php,
making it practically compatible. You just have to take into account
the the new XML namespace and the appropriate filters.

So, to get photos that include a person:

curl -u user:password 'https://example.com/remote.php/dav/files/user/' -X REPORT --data '<?xml version="1.0" encoding="UTF-8"?>
<fr:filter-files
    xmlns:d="DAV:"
    xmlns:nc="http://nextcloud.org/ns"
    xmlns:fr="http://github.com/matiasdelellis/facerecognition/ns">
    <fr:filter-rules>
        <fr:filter-name>Stan Lee</fr:filter-name>
    </fr:filter-rules>
    <d:prop>
        <nc:has-preview/>
    </d:prop>
</fr:filter-files>' | xmllint --format -

...and note that you can ask for all the standard DAV/Nextcloud properties. ;)
@matiasdelellis
Copy link
Owner Author

matiasdelellis commented Dec 26, 2021

More examples:

Images that include some Face Recognition Person:

curl -u user:password https://example.com/remote.php/dav/files/user/ -X REPORT --data '<?xml version="1.0" encoding="UTF-8"?>
<fr:filter-files
    xmlns:d="DAV:"
    xmlns:nc="http://nextcloud.org/ns"
    xmlns:fr="http://github.com/matiasdelellis/facerecognition/ns">
    <fr:filter-rules>
        <fr:filter-name>Stan Lee</fr:filter-name>
    </fr:filter-rules>
    <d:prop>
        <nc:has-preview/>
    </d:prop>
</fr:filter-files>'

Response:

<?xml version="1.0"?>
<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:oc="http://owncloud.org/ns" xmlns:fr="http://github.com/matiasdelellis/facerecognition/ns" xmlns:nc="http://nextcloud.org/ns">
  <d:response>
    <d:status>HTTP/1.1 200 OK</d:status>
    <d:href>/remote.php/dav/files/user/Photos/The%20Big%20Bang%20Theory/bigbangstanlee_1a4795f9.jpg</d:href>
    <d:propstat>
      <d:prop>
        <nc:has-preview>true</nc:has-preview>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
  <d:response>
    <d:status>HTTP/1.1 200 OK</d:status>
    <d:href>/remote.php/dav/files/user/Photos/The%20Big%20Bang%20Theory/Remembering%20Stan%20Lee.jpg</d:href>
    <d:propstat>
      <d:prop>
        <nc:has-preview>true</nc:has-preview>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
  <d:response>
    <d:status>HTTP/1.1 200 OK</d:status>
    <d:href>/remote.php/dav/files/user/Photos/The%20Big%20Bang%20Theory/LOS%20ANGELES/100_511498302.jpg</d:href>
    <d:propstat>
      <d:prop>
        <nc:has-preview>true</nc:has-preview>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
  <d:response>
    <d:status>HTTP/1.1 200 OK</d:status>
    <d:href>/remote.php/dav/files/user/Photos/The%20Big%20Bang%20Theory/LOS%20ANGELES/100_511498340.jpg</d:href>
    <d:propstat>
      <d:prop>
        <nc:has-preview>true</nc:has-preview>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
  <d:response>
    <d:status>HTTP/1.1 200 OK</d:status>
    <d:href>/remote.php/dav/files/user/Photos/The%20Big%20Bang%20Theory/LOS%20ANGELES/100_511498546.jpg</d:href>
    <d:propstat>
      <d:prop>
        <nc:has-preview>true</nc:has-preview>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
  <d:response>
    <d:status>HTTP/1.1 200 OK</d:status>
    <d:href>/remote.php/dav/files/user/Photos/The%20Big%20Bang%20Theory/LOS%20ANGELES/100_511498310.jpg</d:href>
    <d:propstat>
      <d:prop>
        <nc:has-preview>true</nc:has-preview>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
  <d:response>
    <d:status>HTTP/1.1 200 OK</d:status>
    <d:href>/remote.php/dav/files/user/Photos/The%20Big%20Bang%20Theory/LOS%20ANGELES/100_511498314.jpg</d:href>
    <d:propstat>
      <d:prop>
        <nc:has-preview>true</nc:has-preview>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
  <d:response>
    <d:status>HTTP/1.1 200 OK</d:status>
    <d:href>/remote.php/dav/files/user/Photos/The%20Big%20Bang%20Theory/LOS%20ANGELES/100_511498308.jpg</d:href>
    <d:propstat>
      <d:prop>
        <nc:has-preview>true</nc:has-preview>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
  <d:response>
    <d:status>HTTP/1.1 200 OK</d:status>
    <d:href>/remote.php/dav/files/user/Photos/The%20Big%20Bang%20Theory/BURBANK/100_96887756.jpg</d:href>
    <d:propstat>
      <d:prop>
        <nc:has-preview>true</nc:has-preview>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
  <d:response>
    <d:status>HTTP/1.1 200 OK</d:status>
    <d:href>/remote.php/dav/files/user/Photos/The%20Big%20Bang%20Theory/LOS%20ANGELES/100_511493942.jpg</d:href>
    <d:propstat>
      <d:prop>
        <nc:has-preview>true</nc:has-preview>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
  <d:response>
    <d:status>HTTP/1.1 200 OK</d:status>
    <d:href>/remote.php/dav/files/user/Photos/The%20Big%20Bang%20Theory/LOS%20ANGELES/100_511499720.jpg</d:href>
    <d:propstat>
      <d:prop>
        <nc:has-preview>true</nc:has-preview>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
  <d:response>
    <d:status>HTTP/1.1 200 OK</d:status>
    <d:href>/remote.php/dav/files/user/Photos/The%20Big%20Bang%20Theory/LOS%20ANGELES/100_511498508.jpg</d:href>
    <d:propstat>
      <d:prop>
        <nc:has-preview>true</nc:has-preview>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
</d:multistatus>

Favorites files for user:
That's the inspiration behind the implementation, and it works pretty much the same way.. 😉

curl -u user:password https://example.com/remote.php/dav/files/user/ -X REPORT --data '<?xml version="1.0" encoding="UTF-8"?>
<oc:filter-files
    xmlns:d="DAV:"
    xmlns:oc="http://owncloud.org/ns"
    xmlns:nc="http://nextcloud.org/ns">
    <oc:filter-rules>
        <oc:favorite>1</oc:favorite>
    </oc:filter-rules>
    <d:prop>
        <nc:has-preview/>
    </d:prop>
</oc:filter-files>'

Response:

<?xml version="1.0"?>
<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:oc="http://owncloud.org/ns" xmlns:fr="http://github.com/matiasdelellis/facerecognition/ns" xmlns:nc="http://nextcloud.org/ns">
  <d:response>
    <d:status>HTTP/1.1 200 OK</d:status>
    <d:href>/remote.php/dav/files/user/Photos/Steps.jpg</d:href>
    <d:propstat>
      <d:prop>
        <nc:has-preview>true</nc:has-preview>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
  <d:response>
    <d:status>HTTP/1.1 200 OK</d:status>
    <d:href>/remote.php/dav/files/user/Photos/Toucan.jpg</d:href>
    <d:propstat>
      <d:prop>
        <nc:has-preview>true</nc:has-preview>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
  <d:response>
    <d:status>HTTP/1.1 200 OK</d:status>
    <d:href>/remote.php/dav/files/user/Photos/Vineyard.jpg</d:href>
    <d:propstat>
      <d:prop>
        <nc:has-preview>true</nc:has-preview>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
</d:multistatus>

@matiasdelellis
Copy link
Owner Author

matiasdelellis commented Dec 26, 2021

How to get the Face Reccognition Person of a user?

Let's see how to get nextcloud collaborative tags.

Tags for user

curl -u user:password https://example.com/remote.php/dav/systemtags/ -X PROPFIND --data '<?xml version="1.0" encoding="UTF-8"?>
<d:propfind  xmlns:d="DAV:"
    xmlns:oc="http://owncloud.org/ns">
    <d:prop>
        <oc:id />
        <oc:display-name />
        <oc:user-visible />
        <oc:user-assignable />
        <oc:can-assign />
    </d:prop>
</d:propfind>'

Response:

<?xml version="1.0"?>
<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:oc="http://owncloud.org/ns" xmlns:fr="http://github.com/matiasdelellis/facerecognition/ns" xmlns:nc="http://nextcloud.org/ns">
  <d:response>
    <d:href>/remote.php/dav/systemtags/</d:href>
    <d:propstat>
      <d:prop>
        <oc:id/>
        <oc:display-name/>
        <oc:user-visible/>
        <oc:user-assignable/>
        <oc:can-assign/>
      </d:prop>
      <d:status>HTTP/1.1 404 Not Found</d:status>
    </d:propstat>
  </d:response>
  <d:response>
    <d:href>/remote.php/dav/systemtags/113</d:href>
    <d:propstat>
      <d:prop>
        <oc:id>113</oc:id>
        <oc:display-name>Hola</oc:display-name>
        <oc:user-visible>true</oc:user-visible>
        <oc:user-assignable>true</oc:user-assignable>
        <oc:can-assign>true</oc:can-assign>
      </d:prop>
      <d:status>HTTP/1.1 200 OK</d:status>
    </d:propstat>
  </d:response>
</d:multistatus>

Well, the queries will be made to remote.php/dav/systemtags/, the way to register something similar is by adding Sabre/DAV collections, which is out of expectations at this point.. 🤔

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

Successfully merging this pull request may close these issues.

1 participant