Skip to content

Commit

Permalink
Support for XMP metadata in JPEG and TIFF files (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
gino0631 committed Aug 20, 2017
1 parent ba7709b commit a493fe5
Show file tree
Hide file tree
Showing 8 changed files with 459 additions and 926 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Changelog

## [Unreleased]
### Added
- Support for XMP metadata in JPEG and TIFF files

## 0.4.0 – 2017-08-15
### Added
Expand Down
2 changes: 1 addition & 1 deletion appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
See the [README](https://github.com/gino0631/nextcloud-metadata/blob/master/README.md) for the supported file types and limitations.]]>
</description>
<version>0.4.0</version>
<version>0.5.0</version>
<licence>agpl</licence>
<author>gino0631</author>
<category>files</category>
Expand Down
437 changes: 280 additions & 157 deletions lib/Controller/MetadataController.php

Large diffs are not rendered by default.

130 changes: 130 additions & 0 deletions lib/Controller/XmpMetadata.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<?php
namespace OCA\Metadata\Controller;

class XmpMetadata {
const EL_MWG_RS_REGIONS = 'mwg-rs:Regions';
const EL_MWG_RS_NAME = 'mwg-rs:Name';
const EL_MWG_RS_TYPE = 'mwg-rs:Type';
const EL_DC_TITLE = 'dc:title';
const EL_DC_DESCRIPTION = 'dc:description';
const EL_RDF_DESCRIPTION = 'rdf:Description';
const EL_RDF_LI = 'rdf:li';

private $parser;
private $text;
private $data = array();
private $context = array();
private $rsName = null;
private $rsType = null;

public function __construct($xml) {
$this->parser = xml_parser_create('UTF-8');
xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
xml_parser_set_option($this->parser, XML_OPTION_SKIP_WHITE, 0);
xml_set_element_handler($this->parser, array($this, 'startElement'), array($this, 'endElement'));
xml_set_character_data_handler($this->parser, array($this, 'charData'));

xml_parse($this->parser, $xml, true);
}

public function __destruct() {
if (is_resource($this->parser)) {
xml_parser_free($this->parser);
}
}

public function getArray() {
return $this->data;
}

public function startElement($parser, $name, array $attributes) {
$this->text = null;

switch ($name) {
// Elements to remember
case self::EL_MWG_RS_REGIONS:
case self::EL_DC_TITLE:
case self::EL_DC_DESCRIPTION:
$this->contextPush($name);
break;

case self::EL_RDF_DESCRIPTION:
switch ($this->contextPeek()) {
case self::EL_MWG_RS_REGIONS:
if (array_key_exists(self::EL_MWG_RS_NAME, $attributes)) {
$this->rsName = $attributes[self::EL_MWG_RS_NAME];
}
if (array_key_exists(self::EL_MWG_RS_TYPE, $attributes)) {
$this->rsType = $attributes[self::EL_MWG_RS_TYPE];
}
break;
}
break;
}
}

public function endElement($parser, $name) {
if ($this->contextPeek() === $name) {
$this->contextPop();
}

switch ($name) {
case self::EL_MWG_RS_NAME:
$this->rsName = $this->text;
break;

case self::EL_MWG_RS_TYPE:
$this->rsType = $this->text;
break;

case self::EL_RDF_LI:
switch ($this->contextPeek()) { // memorized in startElement()
case self::EL_MWG_RS_REGIONS:
if (($this->rsType === 'Face') && !empty($this->rsName)) {
$this->addVal('people', $this->rsName);
}
$this->rsName = null;
$this->rsType = null;
break;

case self::EL_DC_TITLE:
if (!empty($this->text)) {
$this->addVal('title', $this->text);
}
break;

case self::EL_DC_DESCRIPTION:
if (!empty($this->text)) {
$this->addVal('description', $this->text);
}
break;
}
break;
}
}

public function charData($parser, $data) {
$this->text = $data;
}

protected function addVal($key, $value) {
if (!array_key_exists($key, $this->data)) {
$this->data[$key] = array($value);

} else {
$this->data[$key][] = $value;
}
}

protected function contextPush($var) {
array_push($this->context, $var);
}

protected function contextPop() {
return array_pop($this->context);
}

protected function contextPeek() {
return empty($this->context) ? null : array_values(array_slice($this->context, -1))[0];
}
}
Loading

0 comments on commit a493fe5

Please sign in to comment.