Skip to content

Commit

Permalink
Update to 1.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
af-a1997 committed Jun 10, 2023
1 parent 361b087 commit 924d600
Show file tree
Hide file tree
Showing 20 changed files with 359 additions and 340 deletions.
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# Changelog

## 1.3.0

* Implemented custom output directory choice, now the user may pick where to output the sorted pictures from the sorting criteria picker. This preference **isn't** remembered.
* Coordinates are now extracted before the sorter window opens to ensure the user has at least one geotagged picture, and to help them quickly look for geotagged pictures.
* Updated `MainWindow`'s warning about API keys.
* Added a paste button to API key `Preferences` to paste the API key from the keyboard.
* **Bugfix:** when one picture without geotag is found, that one and any picture scanned afterwards wouldn't have its coordinates stored on the DB.
* **Bugfix:** changing sorting criteria without restarting the program results in the previous sorting criteria being used.
* **Dependency update:** Apache Commons IO to [2.13.0](https://commons.apache.org/proper/commons-io/changes-report.html#a2.13.0).

## 1.2.2

* Fixed coordinates check.
* Re-upgraded OkHttp to latest stable release.

## 1.2.1

* Attempted to fix location not being sent by downgrading OkHttp.

## 1.2.0

* Fixed JDK version, as well as any relevant code to this change.
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ The program works with various open source third-party tools and a [reverse geoc
Read the next section for some important notes regarding the program's functionality.

## :warning: Important
This is the **first** public release of ***GeoPicSorter*** and is early on development, as such, there's a lot of things to be done in order to improve functionality and stability, implement new features, add visual feedback for picture sorting, etc.
***GeoPicSorter*** is early on development, and because of this, there's a lot of things to be done in order to improve its functionality and stability, implement new features, add visual feedback for picture sorting, etc.

Most notoriously, you're limited by the number of daily requests you can make with a free key and require of a stable internet connectivity, you also don't have a visual display of the progress while the program is working on sorting pictures.
Most notoriously, you're limited by the number of daily requests you can make with a free key, and require of a stable internet connection, you also don't have a visual display of the progress while the program is working on sorting pictures, **which makes it look like its frozen while it's actually working in the background**.

Refer to the TODOs project for more details on the list of missing features to be added, I welcome suggestions and contributions, of course.

Expand Down
2 changes: 1 addition & 1 deletion dependency-reduced-pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<groupId>com.afa1997</groupId>
<artifactId>GeoPicSorter</artifactId>
<name>GeoPicSorter</name>
<version>1.2.2</version>
<version>1.3.0</version>
<description>GeoPicSorter is a tool written in Java by Aldo Franquez &lt; af-a1997.github.io &gt;, licensed under GNU AGPL 3.0.

Its goal is to help the user automate the process of organizing geotagged pictures based on groups of locations such as streets, cities, etc.
Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
Its goal is to help the user automate the process of organizing geotagged pictures based on groups of locations such as streets, cities, etc.

Home page: https://af-a1997.github.io/pages/programs/GeoPicSorter/</description>
<version>1.2.2</version> <!-- Version of GeoPicSorter: x.y.z ; where: x = major release, y = minor release, z = hotfix -->
<version>1.3.0</version> <!-- Version of GeoPicSorter: x.y.z ; where: x = major release, y = minor release, z = hotfix -->
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
Expand Down Expand Up @@ -41,7 +41,7 @@ Home page: https://af-a1997.github.io/pages/programs/GeoPicSorter/</description>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.12.0</version>
<version>2.13.0</version>
</dependency>
<dependency>
<groupId>net.lingala.zip4j</groupId>
Expand Down
78 changes: 26 additions & 52 deletions src/main/java/com/afa1997/geopicsorter/features/MetadataMan.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,18 +79,16 @@ public MetadataMan(boolean reset_db) throws SQLException {

// The following two methods are used to get a list of files with one or more extensions. Credit to base code at: < https://mkyong.com/java/how-to-find-files-with-certain-extension-only/ >, I modified it a little to adapt it to GeoPicSorter and return only filenames.
public static List<String> picturesListGen(Path pictures_loc) throws IOException {
if (!Files.isDirectory(pictures_loc)) {
if (!Files.isDirectory(pictures_loc))
throw new IllegalArgumentException("Invalid directory.");
}


List<String> temp_list;
List<String> out_list = new ArrayList<>();
int file_entry = 0;

try (Stream<Path> walk = Files.walk(pictures_loc, 1)) {
temp_list = walk
.filter(p -> !Files.isDirectory(p))
// convert path to string
.map(p -> p.toString())
.filter(f -> pictureHasValidFormat(f))
.collect(Collectors.toList());
Expand All @@ -106,8 +104,8 @@ public static List<String> picturesListGen(Path pictures_loc) throws IOException
}
private static boolean pictureHasValidFormat(String file) {
boolean result = false;
for (String fileExtension : ShStrings.PICTURE_EXTS) {
if (file.endsWith(fileExtension)) {
for (String file_ex : ShStrings.PICTURE_EXTS) {
if (file.endsWith(file_ex)) {
result = true;
break;
}
Expand All @@ -126,33 +124,18 @@ public List<String> MMIF_WriteFileNames(String pictures_location) throws SQLExce

int ft = pictures_fns.size();

if(ft == 0) return null;

try{
String base_command = "INSERT INTO pictures (location, filename) VALUES (";
int detected_pictures = 0;
store_locations_db = DriverManager.getConnection(ShStrings.METADATA_DB);
StringBuilder writing_commands = new StringBuilder();
writing_commands.append(base_command);

// Build the INSERT query to insert various pictures with their locations in one go.
for(int x = 0 ; x < ft ; x++){
if(x == ft-1)
writing_commands.append("\"").append(pictures_location).append("\\\", \"").append(pictures_fns.get(x)).append("\")");
else
writing_commands.append("\"").append(pictures_location).append("\\\", \"").append(pictures_fns.get(x)).append("\"), (");

detected_pictures++;
}
Statement send_location_list_to_db = store_locations_db.createStatement();

// If at least one picture was detected, write the file names into the database.
if(detected_pictures > 0){
writing_commands.append(";");

Statement write_locations_to_db = store_locations_db.createStatement();
write_locations_to_db.executeUpdate(writing_commands.toString());
}
// TODO: add visual feedback for when no pictures are detected.
else
System.out.println(ShStrings.SORTING_STATUS_NO_PICS);
// Queries for storing the picture names.
for(int x = 0 ; x < ft ; x++)
send_location_list_to_db.addBatch("INSERT INTO pictures (location, filename) VALUES (\"" + pictures_location + "\\" + "\", \"" + pictures_fns.get(x) + "\");");

send_location_list_to_db.executeBatch();
} catch(SQLException sql_ex){
sql_ex.getMessage();
} finally {
Expand All @@ -163,32 +146,32 @@ public List<String> MMIF_WriteFileNames(String pictures_location) throws SQLExce
}

// Gets latitude and longitude from each picture and writes it to the database.
public List<String[]> MMIF_GetCoords(String pictures_location) throws SQLException {
List<String[]> out_list_locs = new ArrayList<>();
public int MMIF_GetCoords(String pictures_location) throws SQLException {
// Counter used to keep track of geotagged pictures total, if it's zero, the window for starting the sorting process won't open.
int geotagged_pictures = 0;

try{
store_locations_db = DriverManager.getConnection(ShStrings.METADATA_DB);
String select_command = "SELECT * FROM pictures;";

// Acquire file names at the database.
String select_command = "SELECT * FROM pictures;";
Statement st_sel_fns = store_locations_db.createStatement();
ResultSet rs_sel_fns = st_sel_fns.executeQuery(select_command);

// To create UPDATE command batch onto the database.
Statement st_upd_loc = store_locations_db.createStatement();

// Try to get latitude and longitude for each picture, and writes them into the database if appliable.
String lat = "";
String lng = "";
String lat, lng;

// Navigate through the pictures list to attempt getting coordinates that may be present in each of the pictures.
while(rs_sel_fns.next()){
try {

//File current_picture = new File(pictures_location + rs_sel_fns.getString("filename"));
File current_picture = new File(rs_sel_fns.getString("location") + rs_sel_fns.getString("filename"));

// Get metadata from picture.
md = ImageMetadataReader.readMetadata(current_picture);

// If there's geolocation data, retrieve it:
// If there's geolocation data in the current picture, retrieve it and store it on the database, for use at the sorting process.
if(md.containsDirectoryOfType(GpsDirectory.class)){
GpsDirectory addr = md.getFirstDirectoryOfType(GpsDirectory.class);

Expand All @@ -197,20 +180,12 @@ public List<String[]> MMIF_GetCoords(String pictures_location) throws SQLExcepti

lat = String.valueOf(gl_data.getLatitude());
lng = String.valueOf(gl_data.getLongitude());

st_upd_loc.addBatch("UPDATE pictures SET latitude = " + lat + ", longitude = " + lng + " WHERE id = " + rs_sel_fns.getInt("id") + ";");

geotagged_pictures++;
}
}
// Otherwise, send an empty string to indicate the picture has no coordinates registered:
else{
lat = "";
lng = "";
}

// Add location info to the matching picture in the database, ONLY if both latitude and longitude are present, otherwise keeps the corresponding fields empty, having only one of the parameters makes no sense after all.
if(!lat.isEmpty() && !lng.isEmpty())
st_upd_loc.addBatch("UPDATE pictures SET latitude = " + lat + ", longitude = " + lng + " WHERE id = " + rs_sel_fns.getString("id") + ";");

String[] out_list_locs_d = {rs_sel_fns.getString("filename"), lat, lng};
out_list_locs.add(out_list_locs_d);
} catch (ImageProcessingException | IOException e) {
e.getMessage();
}
Expand All @@ -223,7 +198,6 @@ public List<String[]> MMIF_GetCoords(String pictures_location) throws SQLExcepti
store_locations_db.close();
}

// TODO: List is used for first table recreation to show GPS coordinates, probably won't be necessary but it's going to be evaluated.
return out_list_locs;
return geotagged_pictures;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public PrefMan(){
default_settings_gen.add(new String[]{"sub_by_date", "false"});
default_settings_gen.add(new String[]{"last_work_dir", "."});
default_settings_gen.add(new String[]{"keep_last_work_dir", "true"});
default_settings_gen.add(new String[]{"output_dir", null});
}

// Used when creating settings file for the first time or re-creating it in case of damage/deletion.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,34 +28,14 @@ public class ReverseGeocoding_Geoapify {
static Connection store_locations_db, settings_db;
static String geoapify_api_key = new String();

public List<String[]> RG_SRC0_GetLocNames(int organization_criteria) throws SQLException {
public List<String[]> RG_SRC0_GetLocNames() throws SQLException {
int processed_pictures = 0;
int total_pictures;

List<String[]> return_locations_to_table = new ArrayList<>();

// Keywords related to sorting criterias, most of them are actual API body response keys (in the JSON object) but a few like [continent] aren't, they're here for ease of readability and make the logic below easier to mantain/update.
String org_crit_str;
switch (organization_criteria){
case 0:
org_crit_str = "street";
break;
case 1:
org_crit_str = "city";
break;
case 2:
org_crit_str = "state";
break;
case 3:
org_crit_str = "country";
break;
case 4:
org_crit_str = "continent";
break;

default:
org_crit_str = "street";
}
System.out.println("The sorting criteria is = " + org_crit_str);

try{
store_locations_db = DriverManager.getConnection(ShStrings.METADATA_DB);
Expand All @@ -65,14 +45,37 @@ public List<String[]> RG_SRC0_GetLocNames(int organization_criteria) throws SQLE
Statement st_sel_fns = store_locations_db.createStatement();
Statement save_loc_names = store_locations_db.createStatement();
Statement get_api_key = settings_db.createStatement();
Statement get_sort_pref = settings_db.createStatement();

// Gets the list of pictures in the database.
ResultSet rs_sel_fns = st_sel_fns.executeQuery("SELECT * FROM pictures;");

// Gets the API key stored in the settings.
ResultSet rs_api_key = get_api_key.executeQuery("SELECT s_value FROM settings WHERE s_key = \"api_key\";");
geoapify_api_key = rs_api_key.getString("s_value");
System.out.println("Using API key = " + geoapify_api_key);

// Get sorting criteria value from preferences.
ResultSet rs_sort_crit = get_sort_pref.executeQuery("SELECT s_value FROM settings WHERE s_key = \"organization_criteria\";");
switch (rs_sort_crit.getInt("s_value")){
case 0:
org_crit_str = "street";
break;
case 1:
org_crit_str = "city";
break;
case 2:
org_crit_str = "state";
break;
case 3:
org_crit_str = "country";
break;
case 4:
org_crit_str = "continent";
break;

default:
org_crit_str = "street";
}

// Counts total of pictures to log into console.
// TODO: remove and implement proper progress display, maybe logging to file too.
Expand Down Expand Up @@ -105,8 +108,6 @@ public List<String[]> RG_SRC0_GetLocNames(int organization_criteria) throws SQLE
if(api_response_arr.getJSONObject(0).has(org_crit_str)){
String location_name = api_response_arr.getJSONObject(0).getString(org_crit_str);

System.out.println(location_name);

save_loc_names.addBatch("UPDATE pictures SET location_name = \"" + location_name + "\" WHERE id = " + rs_sel_fns.getString("id") + ";");

return_locations_to_table.add(new String[]{rs_sel_fns.getString("filename"), rs_sel_fns.getString("latitude"), rs_sel_fns.getString("longitude"), location_name});
Expand Down Expand Up @@ -156,7 +157,7 @@ public List<String[]> RG_SRC0_GetLocNames(int organization_criteria) throws SQLE
Thread.sleep(250);
}

// No matter the criteria, if either or both latitude and longitude info is missing then put the "geotag-less" pictures on a dedicated folder.
// No matter the criteria, if either or both latitude and longitude info is missing, then put the "geotag-less" pictures on a dedicated folder.
else if(rs_sel_fns.getString("latitude") == null || rs_sel_fns.getString("longitude") == null){
save_loc_names.addBatch("UPDATE pictures SET location_name = \"" + ShStrings.FOLDER_NO_GEOTAG + "\" WHERE id = " + rs_sel_fns.getString("id") + ";");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ public class ShStrings {

// Project related values.
public static final String PROG_NAME = "GeoPicSorter";
public static final String PROG_VER = "1.2.2";
public static final String PROG_VER = "1.3.0";
public static final String PROG_NAME_FULL = PROG_NAME + " " + PROG_VER;
public static final String REPO_LOC = "https://github.com/af-a1997/GeoPicSorter";

// Sorting status messsages.
public static final String SORTING_STATUS_IDLE = "Not started";
public static final String SORTING_STATUS_IDLE = " picture(s) have been detected. Awaiting start.";
public static final String SORTING_STATUS_IDLE_SHORT = "Awaiting start";
public static final String SORTING_STATUS_NO_PICS = "No pictures detected in this folder";
public static final String SORTING_STATUS_DETECTING = "Detecting pictures...";
public static final String SORTING_STATUS_FETCH_GEOTAGS = "Fetching geolocation data...";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,16 @@ public SortingAct(String output_location) throws FileNotFoundException, IOExcept
// Selects pictures list and loads file handling preference.
ResultSet rs_sel_fns = st_sel_fns.executeQuery("SELECT * FROM pictures;");
ResultSet rs_get_prefs_sortact = st_get_prefs.executeQuery("SELECT s_value FROM settings WHERE s_key = \"sort_act\";");

int psa_v = rs_get_prefs_sortact.getInt("s_value");

while(rs_sel_fns.next()){
String orig_dir = rs_sel_fns.getString("location");
if(orig_dir == null)
orig_dir = ShStrings.FOLDER_NO_GEOTAG;

File dest_dir = new File(orig_dir + rs_sel_fns.getString("location_name"));
//File dest_dir = new File(output_location);
File dest_dir = new File(output_location + "\\" + rs_sel_fns.getString("location_name"));
File origin_pict = new File(orig_dir + rs_sel_fns.getString("filename"));
File destination = new File(dest_dir + "\\" + rs_sel_fns.getString("filename"));

Expand Down
Loading

0 comments on commit 924d600

Please sign in to comment.