Can someone please explain how to embed metadata into a custom metadata field in an MP4 file with exiftool? I've searched all the docs and it seems to be related to the config file that needs to be created. Here is what I'm working with. (I know this isnt even close, as its not doing XMP fields, but I havent found a single working example with XMP fields yet.
%Image::ExifTool::UserDefined = (
'Image::ExifTool::Exif::Main' => {
0xd001 => {
Name => 'Show',
Writable => 'string',
WriteGroup => 'IFD0',
},
);
1; #end
The command I'm trying to run is:
exiftool -config exifToolConfig -show="Lightning" /reachengine/media/mezzanines/2015/02/13/13/CanyonFlight.mp4
Running this in a linux environment.
What is the properly way to set XMP metadata on custom metadata fields via ExifTool in linux on MP4 files?
The sample exiftool config file contains a number of working examples of custom XMP tags.
Basically, it is done like this:
%Image::ExifTool::UserDefined = (
'Image::ExifTool::XMP::Main' => {
xxx => {
SubDirectory => {
TagTable => 'Image::ExifTool::UserDefined::xxx',
},
},
},
);
%Image::ExifTool::UserDefined::xxx = (
GROUPS => { 0 => 'XMP', 1 => 'XMP-xxx', 2 => 'Other' },
NAMESPACE => { 'xxx' => 'http://ns.myname.com/xxx/1.0/' },
WRITABLE => 'string',
MyNewXMPTag => { },
);
Then the command is
exiftool -config myconfig -mynewxmptag="some value" myfile.mp4
Related
I need to add new tags to many images, the tags are:
AboveGroundAltitude
BandName
CentralWaveLength
ColorTransform
PerspectiveDistortion
PerspectiveFocalLength
PrincipalPoint
WavelengthFWHM
I created this configuration file:
%Image::ExifTool::UserDefined = (
'Image::ExifTool::XMP::xmp' => {
NewXMPxmpTag => { Groups => { 1 => 'AboveGroundAltitude' } },
NewXMPxmpTag => { Groups => { 1 => 'BandName' } },
NewXMPxmpTag => { Groups => { 1 => 'CentralWaveLength' } },
NewXMPxmpTag => { Groups => { 1 => 'ColorTransform' } },
NewXMPxmpTag => { Groups => { 1 => 'PerspectiveDistortion' } },
NewXMPxmpTag => { Groups => { 1 => 'PerspectiveFocalLength' } },
NewXMPxmpTag => { Groups => { 1 => 'PrincipalPoint' } },
NewXMPxmpTag => { Groups => { 1 => 'WavelengthFWHM' } },
},
);
Variations: I've tried group 0 the first time, then read somewhere that XMP tags belong to group 1 and edited accodingly.
And I'm running the command like this:
exiftool -config config.txt -ext jpg \
-AboveGroundAltitude='55.8224668413325'\
-BandName='Red, Garbage, NIR'\
-CentralWaveLength='625, 0, 850'\
-ColorTransform='1.000, 0.000, -0.996, 0.000, 0.000, 0.000, -0.286, 0.000, 4.350'\
-PerspectiveDistortion='-0.093, 0.122, 0.000, 0.000, 0.000'\
-PerspectiveFocalLength='5.4'
-PrincipalPoint='3.100, 2.325'\
-WavelengthFWHM='100, 0, 40' test.jpg
Variations tried:
- -xmp:AboveGroundAltitude='55.8224668413325'
- -XMP-AboveGroundAltitude='55.8224668413325'
- -XMP-xmp:AboveGroundAltitude='55.8224668413325'
- all the three above with `+=` between the tag and the value
Also note the backslashes were added here for clarity, my original command is a one liner with no newlines nor backslashes.
The error I'm getting is (I'm using a mix of options tried here to illustrate different error messages, but when I tried them the style for options were normalized at each try):
Also, used -v4 for more verbose logging
exiftool -config config.txt -v4 -ext jpg -XMP-AboveGroundAltitude='55.8224668413325' -xmp:BandName='Red, Garbage, NIR' -XMP-xmp:CentralWaveLength='625, 0, 850' -xmp:ColorTransform='1.000, 0.000, -0.996, 0.000, 0.000, 0.000, -0.286, 0.000, 4.350' -PerspectiveDistortion='-0.093, 0.122, 0.000, 0.000, 0.000' -xmp:PerspectiveFocalLength='5.4' -xmp:PrincipalPoint='3.100, 2.325' -xmp:WavelengthFWHM='100, 0, 40' test.jpg
Tag 'XMP-AboveGroundAltitude' is not defined or has a bad language code
Warning: Tag 'XMP-AboveGroundAltitude' is not defined or has a bad language code
Tag 'xmp:BandName' is not defined
Warning: Tag 'xmp:BandName' is not defined
Tag 'XMP-xmp:CentralWaveLength' is not defined
Warning: Tag 'XMP-xmp:CentralWaveLength' is not defined
Sorry, xmp:ColorTransform doesn't exist or isn't writable
Warning: Sorry, xmp:ColorTransform doesn't exist or isn't writable
Tag 'PerspectiveDistortion' is not defined
Warning: Tag 'PerspectiveDistortion' is not defined
Tag 'xmp:PerspectiveFocalLength' is not defined
Warning: Tag 'xmp:PerspectiveFocalLength' is not defined
Tag 'xmp:PrincipalPoint' is not defined
Warning: Tag 'xmp:PrincipalPoint' is not defined
Tag 'xmp:WavelengthFWHM' is not defined
Warning: Tag 'xmp:WavelengthFWHM' is not defined
Nothing to do.
Notice how the message for ColorTransform is different
Note: Already seen enter link description here and other related posts here and in the exiftool forum.
I found a configuration file made by the camera maker, which I'll paste below:
#------------------------------------------------------------------------------
# File: xmp_camera_tags.config
#
# Description: Adds capability to modify all XMP camera tags
#
#------------------------------------------------------------------------------
%Image::ExifTool::UserDefined = (
'Image::ExifTool::XMP::Main' => {
Camera=> {
SubDirectory => {
TagTable => 'Image::ExifTool::UserDefined::Camera',
},
},
},
);
%Image::ExifTool::UserDefined::Camera = (
GROUPS => { 0 => 'XMP', 1 => 'XMP-Camera', 2 => 'Other' },
NAMESPACE => { 'Camera' => 'http://pix4d.com/Camera/1.0/' },
WRITABLE => 'string',
GPSXYAccuracy=> {},
GPSZAccuracy => {},
Pitch => {},
Roll=>{},
Yaw => {},
BandName => { List => 'Seq' },
CentralWavelength => { List => 'Seq' },
WavelengthFWHM => { List => 'Seq' },
BandSensitivity => { List => 'Seq' },
ColorTransform => { List => 'Seq' },
);
%Image::ExifTool::UserDefined::camera = (
GROUPS => { 0 => 'XMP', 1 => 'XMP-Camera', 2 => 'Other' },
NAMESPACE => { 'Camera' => 'http://pix4d.com/Camera/1.0/' },
);
#------------------------------------------------------------------------------
and used that as a template to add the missing tags I needed.
The relevant model info for the Sentera camera is:
LensModel : 5.4mm-0001_0015
Model : 21021-03_12MP-ERS-0001
Original problem was my employee took a first batch (near 8000) of aerial photos with an old firmware. Later he updated the firmware and did the rest of the work. So when trying to process the images, the ones taken first would produce errors and the processing software refused to work.
Thanks anyway #StartGeek for your comments :)
Clearly my attempt was far, far away from what was needed, but the urgency didn't allow me time to investigate further the proper way to configure Exiftool.
In Suitecrm have a subpanel and when clicking 'Select' I want it to show only a specific set of records.
I have a subpanel definition file that looks like this and tried all possible variations in the section "initial_filter" but when the pop-up comes up it shows all of the records
$layout_defs["un_inventory"]["subpanel_setup"]['un_inventory_leads_1'] = array (
'order' => 0,
'module' => 'Leads',
'subpanel_name' => 'default',
'sort_order' => 'asc',
'sort_by' => 'id',
'title_key' => 'LBL_UN_INVENTORY_LEADS_1_FROM_LEADS_TITLE',
//'get_subpanel_data' => 'un_inventory_leads_1',
'get_subpanel_data' => 'function:get_parent_leads',
'function_parameters' =>
array('import_function_file' => 'custom/modules/Leads/func/get_parent_leads_file.php',),
'top_buttons' =>
array (
0 =>
array (
'widget_class' => 'SubPanelTopButtonQuickCreate',
),
1 =>
array (
//'widget_class' => 'SubPanelTopSelectButton',
'widget_class' => 'SubPanelTopSelectButtonParentProjectLeads',
'mode' => 'MultiSelect',
// 'initial_filter_fields' => "&first_name_advanced=hello",
// 'initial_filter' => array('parent_project_id_c_advanced' => array('83b30b20-83a6-8099-b3b9-5d4a491888e6')),
// 'initial_filter' => array('parent_project_id_c_advanced' => '83b30b20-83a6-8099-b3b9-5d4a491888e6'),
// 'initial_filter' => array('account_type_advanced' => array('Student')),
// 'initial_filter' => '&parent_project_id_c=83b30b20-83a6-8099-b3b9-5d4a491888e6',
),
),
);
There are many example of how this is done for 'relate' fields in editview, but not so much for subpanel's such as above, I'm pretty sure many would find this valuable.
Solution would probably be applicable to sugarcrm CE also
Solution is to override the default TopButtonSelect class and hardcode the $initial_filter variable.
So if we hardcode the value like so
$initial_filter.='&parent_project_id_c_advanced='.urlencode("83b30b20-83a6-8099-b3b9-5d4a491888e6");
It will only show records which have the parent_project_id_c field with the value 83b30b20-83a6-8099-b3b9-5d4a491888e6
Hope this helps
Source: http://qc-digital.com/filter-values-shown-when-we-click-on-select-button-inside-a-subpanel/
The above soluton proposed by Robert Sinclair does work, but it creates a dedicated-use situation. If instead you wanted to create a solution that will let you use the changes to have a functional initial_filter for any subpanel, make the following edits.
Thank you to Robert Sinclair and qc-digital.com for not only showing how to make his solution work but also for explaining why the expected method does not work, enabling the edits below to fix the SugarWidget and have it behave as expected.
Two fixes in this post:
a) Have the initial_filter_fields array be checked against the target
module not the host module
b) have the key=>value arrangement in the
layoutdefs work like it does in other situations
Two steps to make this fix work:
Create a custom SugarWidget
Tell the subpanel to use the custom SugarWidget and add the initial_filter_fields array to the TopSelectButton definition
You can then use the custom SugarWidget in any other subpanel and the initial_filter_field will work
Create the custom SugarWidget
mkdir -p custom/include/generic/SugarWidgets/
cp -a include/generic/SugarWidgets/SugarWidgetSubPanelTopSelectButton.php custom/include/generic/SugarWidget/SugarWidgetSubPanelTopSelectButtonWithFilter.php
nano custom/include/generic/SugarWidgets/SugarWidgetSubPanelTopSelectButtonWithFilter.php
Change
class SugarWidgetSubPanelTopSelectButton extends SugarWidgetSubPanelTopButton
To
class SugarWidgetSubPanelTopSelectButtonWithFilter extends SugarWidgetSubPanelTopButton
Change
if (isset($widget_data['initial_filter_fields'])) {
if (is_array($widget_data['initial_filter_fields'])) {
foreach ($widget_data['initial_filter_fields'] as $value=>$alias) {
if (isset($focus->$value) and !empty($focus->$value)) {
$initial_filter.="&".$alias . '='.urlencode($value);
}
}
}
}
To
/*
* Edited Below to use the target module not the host module
* and to use the normal key=>value arrangement
if (isset($widget_data['initial_filter_fields'])) {
if (is_array($widget_data['initial_filter_fields'])) {
foreach ($widget_data['initial_filter_fields'] as $value=>$alias) {
if (isset($focus->$value) and !empty($focus->$value)) {
$initial_filter.="&".$alias . '='.urlencode($value);
}
}
}
}
*/
if (isset($widget_data['initial_filter_fields'])) {
if (is_array($widget_data['initial_filter_fields'])) {
foreach ($widget_data['initial_filter_fields'] as $alias=>$value) {
$initial_filter.="&".$alias . '='.urlencode($value);
}
}
}
Tell the subpanel to use the custom SugarWidget (in my case, editing the Events module (FP_events) subpanel I created pointing to Accounts ... edit to suit your situation)
nano custom/Extension/modules/FP_events/Ext/Layoutdefs/fp_events_accounts_1_FP_events.php
Change
array (
'widget_class' => 'SubPanelTopSelectButton',
'mode' => 'MultiSelect',
),
To
array (
'widget_class' => 'SubPanelTopSelectButtonWithFilter',
'mode' => 'MultiSelect',
'initial_filter_fields' => array(
'account_type_advanced' => 'Venue',
),
),
You will now be able to use the initial_filter_fields functionality in any subpanel by specifying the custom SugarWidget and including the initial_filter_fields array definition in the TopSelectButton definition.
We are unable to create the new ticket in Jira using REST-API via Perl script.
Note: Without custom field script successfully executing. please provide the suggestion to add a custom field in my script.
Screenshot for the custom field.
Error Message:
JIRA::REST Error[400 - Bad Request]:
- [custom_field] Field 'custom_field' cannot be set. It is not on the appropriate screen, or unknown.at copy_of_new-jira.pl line 16.
Perl Script :
#Loading the modules from a specific location such that JIRA::REST.
use JIRA::Client::Automated;
use JIRA::REST;
use Data::Dumper;
#Login details about Jira server
my $jira = JIRA::REST->new({
url => 'https://xxxxxxxx.xxxxx.com',
username => 'xxxxxxx',
password => 'xxxxxxx',
});
# Create the ticket using post function
my $issue = $jira->POST('/issue', undef, {
fields => {
project => { key => 'TIME' },
issuetype => { name => 'Task' },
summary => '20-7-2018 checking field persent or not',
description => 'test',
custom_field => { Epic Link => 'Application Framework'},
},
});
It looks like you're missing some quote marks in your fields->custom_field data structure:
# Create the ticket using post function
my $issue = $jira->POST('/issue', undef, {
fields => {
project => { key => 'TIME' },
issuetype => { name => 'Task' },
summary => '20-7-2018 checking field persent or not',
description => 'test',
custom_field => { 'Epic Link' => 'Application Framework'},
},
});
There's also a typo in summary, but presumably that doesn't matter too much.
I'm trying to use ELK pipeline to read an email (IMAP), extract generic attachments (mainly PDF, eventually doc or ppt) and put them on ElasticSearch.
This is what I was able to do:
Loading directly to ElasticSearch from file some base64 data using Logstash, using the Ingest Attachment Processor on ElasticSearch to read the base64 content.
Loading data from IMAP (exchange email) I can correctly load all email information on ElasticSearch except the attachment (what I need).
The first solution works fine and does what I am looking for, except that it doesn't extract attachments directly from the email and that I have hardcoded base64 data inside the files.
With the second solution I have a field x-ms-has-attach: yes on Kibana, but there isn't anywhere the attachment itself. The imap plugin is intended to load only the content of the email without the attachment?
What am I missing? Could you suggest me a pipeline to achieve what I am looking for?
This is my logstash configuration for the first example:
input {
file {
path => "/my/path/to/data/*"
start_position => "beginning"
# sincedb_path => "/my/path/to/sincedb"
sincedb_path => "/dev/null"
close_older => 0
tags => ["attachment"]
}
}
output {
elasticsearch {
index => "email-attachment"
hosts => [ "localhost:9200" ]
}
}
This is the pipeline:
PUT _ingest/pipeline/email-attachment
{
"description": "Pipeline to parse an email and its attachments",
"processors": [
{
"attachment" : {
"field" : "message"
}
},
{
"remove" : {
"field" : "message"
}
},
{
"date_index_name" : {
"field" : "#timestamp",
"index_name_prefix" : "email-attachment-",
"index_name_format": "yyyy-MM",
"date_rounding" : "M"
}
}
]
}
This is my logstash configuration for the second example:
input {
imap {
host => "my.domain.it"
password => "mypassword"
user => "myuser"
port => 12345
type => "imap"
secure => true
strip_attachment => true
}
}
output {
elasticsearch {
index => "email-attachment"
hosts => [ "localhost:9200" ]
}
}
UPDATE
I'm using version 5.2.2
In the end I defined a totally different pipeline.
I read emails using a Ruby application with the mail library (you can find it on github), where it's quite easy to extract attachments.
Then I put the base64 encoding of those attachments directly on ElasticSearch, using Ingest Attachment Processor.
I filter on content_type just to be sure to load only "real" attachments, as the multiparts emails treat any multimedial content in the body (ie: images) as attachment.
P.S.
Using the mail library, you should do something like:
Mail.defaults do
retriever_method :imap, { :address => address,
:port => port,
:user_name => user_name,
:password => password,
:enable_ssl => enable_ssl,
:openssl_verify_mode => openssl_verify_mode }
and new_messages = Mail.find(keys: ['NOT','SEEN']) to retrieve unseen messages.
Then iterate over new_messages. After, you can encode a message simply using encoded = Base64.strict_encode64(attachment.body.to_s). Please inspect new_messages to check the exact field names to use.
Your problem might come from strip_attachment => true in the imap input plugin.
my controller file inside api/v1/controller/
class ProfileController extends ActiveController
{
public $modelClass = 'app\models\Profile';
public function behaviors()
{
return [
[
'class' => 'yii\filters\ContentNegotiator',
'only' =>
['index', 'view', 'createnew','update','search'],
'formats' =>
['application/json' => Response::FORMAT_JSON,],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'index' => ['get'],
'view' => ['get'],
'createnew' => ['post'],
'update' => ['put'],
'delete' => ['delete'],
'deleteall' => ['post'],
'search' => ['get']
],
]
];
}
public function actionCreatenew() {
$model = new Profile();
$model->load(Yii::$app->request->post());
$model->asset = UploadedFile::getInstance($model, 'asset');
$name = $model->user_id;
if($model->asset) {
$model->asset->saveAs('uploads/'.$name.'.
'.$model->asset->extension);
$model->asset = $model->asset->name.'.'.
$model->asset->extension;
}
if($model->save()) {
echo json_encode(array('status'=>"Success",
'data'=>$model->attributes),JSON_PRETTY_PRINT);
} else {
echo json_encode(array('status'=>"Failure",
'error_code'=>400,
'errors'=>$model->errors),JSON_PRETTY_PRINT);
}
}
}
When I try to use access this from Postman like:
POST http://localhost/myapp/api/v1/profiles
I get Invalid Parameter – yii\base\InvalidParamException
Response content must not be an array.
What is the issue?? help would be grateful!! Thanks
You can easily receive single / multi-uploaded files using HTTP POST with form-data encoding in Yii2, directly in your Yii2 Controller / action.
Use this code:
$uploads = UploadedFile::getInstancesByName("upfile");
if (empty($uploads)){
return "Must upload at least 1 file in upfile form-data POST";
}
// $uploads now contains 1 or more UploadedFile instances
$savedfiles = [];
foreach ($uploads as $file){
$path = //Generate your save file path here;
$file->saveAs($path); //Your uploaded file is saved, you can process it further from here
}
If you use Postman API client to test how your API is working, you can configure the upload endpoint to work like this for multi-file uploads:
Note: The upfile[] square brackets are important! Postman will happily let you select multiple files for upload in one slot, but this will not actually work. Doing it the way shown in the screenshot makes an array of files available to the Yii2 action, through the UploadedFile mechanism. This is roughly equivalent to the standard PHP $_FILES superglobal variable but with easier handling.
Single files can be uploaded with or without the [] square brackets after the key name. And of course you can name upfile whatever you like, for your convention.
You should use \yii\web\UploadedFile::getInstanceByName('asset'); instead of getInstance() checkout this Link