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

Add cli tool to handle EXIF metadata #140

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ jobs:
- name: Install Dependencies
run: |
apt update
apt install -y exif meson
- name: Test Metadata
run: bash tests.sh
apt install -y libgexiv2-dev meson valac
- name: Build
run: |
meson build
ninja -C build
- name: Test Metadata
run: bash tests.sh
- name: Install
run: |
ninja -C build install
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
*~
build
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ You should avoid busy parts of the wallpaper in the top panel and bottom dock ar
1. Make sure your wallpaper is openly-licensed and okay for commercial use (see below)
2. Fork the project and add the wallpaper
3. Add license info to the `debian/copyright` file
4. Add artist exif metadata using command `exiftool -artist="Vincent van Gogh" The\ Starry\ Night.jpg`
5. Create a pull request.
4. Build the command line tool: `meson build --prefix=/usr && ninja -C build`
5. Add artist exif metadata using command `./build/src/io.elementary.wallpapers --artist "Ashim D'Silva" backgrounds/Ashim\ DSilva.jpg`
6. Add accent color exif metadata using command `./build/src/io.elementary.wallpapers --accent-color Orange backgrounds/Ashim\ DSilva.jpg`
7. Create a pull request.

Due to the nature of this repository, very few pull requests will be accepted.

Expand Down
5 changes: 5 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
project(
'io.elementary.wallpapers',
'c', 'vala',
version: '5.5.0'
)

Expand All @@ -10,5 +11,9 @@ install_subdir(
install_dir: get_option('datadir')
)

glib_dep = dependency('glib-2.0')
gexiv2_dep = dependency('gexiv2')

subdir('data')
subdir('po')
subdir('src')
204 changes: 204 additions & 0 deletions src/Application.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
/*
* Copyright 2021 elementary, Inc. (https://elementary.io)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*
* Authored by: Marius Meisenzahl <mariusmeisenzahl@gmail.com>
*/

public class Wallpapers.Application : GLib.Application {
private const string TAG_ARTIST = "Exif.Image.Artist";
private const string TAG_ACCENT_COLOR = "Xmp.xmp.io.elementary.AccentColor";

private static string? artist = null;
private static string? accent_color = null;
private static bool lint = false;

private ApplicationCommandLine application_command_line;

private const string[] VALID_COLORS = {
"Red",
"Orange",
"Yellow",
"Green",
"Mint",
"Blue",
"Purple",
"Pink",
"Brown",
"Gray"
};

private const OptionEntry[] OPTIONS = {
{ "artist", 'a', 0, OptionArg.STRING, ref artist,
"Set artist" },
{ "accent-color", 'c', 0, OptionArg.STRING, ref accent_color,
"Set accent color" },
{ "lint", 'l', 0, OptionArg.NONE, ref lint,
"Lint wallpapers" },
{ null }
};

private Application () {
Object (
application_id: "io.elementary.wallpapers",
flags: ApplicationFlags.HANDLES_COMMAND_LINE
);
}

public override int command_line (ApplicationCommandLine command_line) {
this.hold ();

int res = handle_command_line (command_line);

this.release ();
return res;
}

private int handle_command_line (ApplicationCommandLine command_line) {
string[] args = command_line.get_arguments ();

if (args.length == 1) {
args = { args[0], "." };
}

unowned string[] tmp = args;

try {
var option_context = new OptionContext ("");
option_context.set_help_enabled (true);
option_context.add_main_entries (OPTIONS, null);

option_context.parse (ref tmp);
} catch (OptionError e) {
command_line.print ("Error: %s\n", e.message);
command_line.print ("Run '%s --help' to see a full list of available options.\n", args[0]);
return 1;
}

this.application_command_line = command_line;

int errors = 0;
string[] file_name_list = tmp[1:tmp.length];

if (artist != null) {
if (artist.length >= 3) {
for (int i = 0; i < file_name_list.length; i++) {
print ("Set artist of \"%s\" to %s\n", file_name_list[i], artist);
try {
set_artist (file_name_list[i], artist);
} catch (Error e) {
print ("ERROR: Setting artist of \"%s\": %s", file_name_list[i], e.message);
errors++;
}
}
} else {
print ("ERROR: \"%s\" is not a valid artist\n", artist);
errors++;
}
}

if (accent_color != null) {
if (accent_color in VALID_COLORS) {
for (int i = 0; i < file_name_list.length; i++) {
print ("Set accent color of \"%s\" to %s\n", file_name_list[i], accent_color);
try {
set_accent_color (file_name_list[i], accent_color);
} catch (Error e) {
print ("ERROR: Setting accent color of \"%s\": %s", file_name_list[i], e.message);
errors++;
}
}
} else {
print ("ERROR: \"%s\" is not a valid accent color\n", accent_color);
print ("Valid colors are:\n");
for (int i = 0; i < VALID_COLORS.length; i++) {
print (" %s\n", VALID_COLORS[i]);
}
errors++;
}
}

if (lint) {
GExiv2.Metadata metadata;
string? value;
for (int i = 0; i < file_name_list.length; i++) {
try {
metadata = new GExiv2.Metadata ();
metadata.open_path (file_name_list[i]);

print ("Image: %s\n", file_name_list[i]);

value = metadata.get_tag_string (TAG_ARTIST);
if (value == null) {
print ("ERROR: Artist is not set\n");
errors++;
} else if (value.length < 3) {
print ("ERROR: Artist length is less than 3 characters\n");
errors++;
} else {
print ("Artist: %s\n", value);
}

value = metadata.get_tag_string (TAG_ACCENT_COLOR);
if (value == null) {
print ("ERROR: %s is not set\n", TAG_ACCENT_COLOR);
errors++;
} else if (!(value in VALID_COLORS)) {
print ("ERROR: \"%s\" is not a valid accent color\n", accent_color);
print ("Valid colors are:\n");
for (int j = 0; j < VALID_COLORS.length; j++) {
print (" %s\n", VALID_COLORS[j]);
}
errors++;
} else {
print ("AccentColor: %s\n", value);
}

print ("\n");
} catch (Error e) {
print ("ERROR: Parsing exif metadata of \"%s\": %s", file_name_list[i], e.message);
errors++;
}
}
}

return errors;
}

private void set_artist (string path, string artist) throws Error {
var metadata = new GExiv2.Metadata ();
metadata.open_path (path);

metadata.set_tag_string (TAG_ARTIST, artist);

metadata.save_file (path);
}

private void set_accent_color (string path, string accent_color) throws Error {
var metadata = new GExiv2.Metadata ();
metadata.open_path (path);

metadata.set_tag_string (TAG_ACCENT_COLOR, accent_color);

metadata.save_file (path);
}

public static int main (string[] args) {
var app = new Application ();
return app.run (args);
}
}
13 changes: 13 additions & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
sources = files(
'Application.vala',
)

executable(
meson.project_name(),
sources,
dependencies: [
glib_dep,
gexiv2_dep,
],
install: false,
)
16 changes: 2 additions & 14 deletions tests.sh
Original file line number Diff line number Diff line change
@@ -1,22 +1,10 @@
#!/bin/sh
set -e

# Ensure Artist metadata is not corrupt, does exist and at least 3 chars
test_artist () {
print_error () {
echo "Failure! $1 missing Artist metadata! See README.md."
exit 1
}

ARTIST="$(exif --tag=Artist --no-fixup -m "$1")" || print_error "$1"
if [ "$(echo "$ARTIST" | wc -m)" -lt 3 ]; then
print_error "$1"
fi
}

for WALLPAPER in backgrounds/*.jpg
do
test_artist "$WALLPAPER"
./build/src/io.elementary.wallpapers --lint "$WALLPAPER"
done

echo "Success! Wallpapers have Artist metadata."
echo "Success! Wallpapers have valid metadata."