Skip to content

Commit

Permalink
sharing source
Browse files Browse the repository at this point in the history
  • Loading branch information
alsemenov committed Jan 9, 2015
1 parent fa0c5b0 commit 389098f
Show file tree
Hide file tree
Showing 15 changed files with 2,193 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target
4 changes: 3 additions & 1 deletion README.RUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ Finmerge сравнивает входные файлы с результато
* Составные транзакции не поддерживаются (я их не использую и не проверял)
* Бюджеты и местоположения должны работать, но это не протестировано.
* Конфликт редактирования одной и той же записи на разных устройствах технически не разрешен.
Необходимо решать его через договоренности между людьми.
Необходимо решать его через договоренности между людьми.
* Я не публикую входные данные для тестов, потому что это мои реальные финансовые данные.
По этой причине все тесты закоментированы.

Поддержка
=========
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Current limitations
* Splitted transactions are not tested/supported (because I do not use them :-) )
* Budget, locations should work well, but not tested
* Conflict of editing the same entity by different persons is not resolved technically. It should be resolved by agreement between persons.
* I had to exclude test data from publishing, because it is my real financial data. All tests are commented.

Support
=======
Expand Down
56 changes: 56 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>ru.xibodoh</groupId>
<artifactId>finmerge</artifactId>
<version>1.0.4</version>
<packaging>jar</packaging>
<licenses>
<license>
<name>GNU GENERAL PUBLIC LICENSE Version 2, June 1991</name>
<url>http://www.gnu.org/licenses/old-licenses/gpl-2.0.html</url>
</license>
</licenses>

<name>finmerge</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>ru.xibodoh.finmerge.Tool</mainClass>
<packageName>ru.xibodoh.finmerge</packageName>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
159 changes: 159 additions & 0 deletions src/main/java/ru/xibodoh/finmerge/App.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/*
~ Copyright (c) 2014-2015 Aleksei Semenov (aka xibodoh)
~ All rights reserved. This program and the accompanying materials
~ are made available under the terms of the GNU Public License v2.0
~ which accompanies this distribution, and is available at
~ http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*/
package ru.xibodoh.finmerge;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import ru.xibodoh.finmerge.financisto.BackupFile;

public class App {

private static final Logger logger = Logger.getLogger(App.class.getName());

private static final String USAGE = "Usage: java "+App.class.getName()+" [-logLevel level] {-in inputFile} [-out outputFile]\n"+
"\t level - logging level: SEVERE,WARNING,INFO,FINE,FINER,FINEST,ALL\n"+
"\t inputFile - input file or folder name\n"+
"\t\tIf folder is given, the most recent backup file in it will be selected.\n"+
"\t outputFile - output file name, where to write merge result.\n"+
"\t\tIf omitted, the result will be written in every input folder.\n"+
"\t\tIf there are no input folders, the result will be written to current folder.";

public static void main( String[] args ) {
String logLevel = null;
List<File> inputFiles = new ArrayList<File>();
String outputName = null;
for(int i=0; i<args.length; i++){
String arg = args[i];
if ("-logLevel".equals(arg) && i+1<args.length){
logLevel = args[++i];
} else if ("-in".equals(arg) && i+1<args.length){
inputFiles.add(new File(args[++i]));
} else if ("-out".equals(arg) && i+1<args.length) {
outputName = args[++i];
}
}

Log.configure(logLevel);
if (inputFiles.isEmpty()){
logger.info(USAGE);
return;
}

List<File> outputFolders = new ArrayList<File>();
if (outputName!=null) {
outputFolders.add(new File(outputName).getParentFile());
}
BackupFile result = null;
String minInputName = null;
for (File file: inputFiles){
if (file.isDirectory()){
if (outputName==null){
outputFolders.add(file);
}
file = findMostRecentBackupFile(file);
}

if (file.isFile()){
if (minInputName==null || minInputName.compareTo(file.getName())>0){
minInputName = file.getName();
}
try {
BackupFile backupFile = new BackupFile(file);
logger.log(Level.INFO, "Loaded file {0}", file.getAbsolutePath());
if (result==null){
result = backupFile;
} else {
result.merge(backupFile);
}
} catch (Exception e) {
logger.log(Level.WARNING, "Failed to read file {0}: {1}", new Object[]{file.getAbsolutePath(), e.getMessage()});
}
}
}

if (result!=null){
if (outputName==null){
outputName = "merged_"+minInputName;
}
for (File folder: outputFolders) {
File file = new File(folder, outputName);
try {
result.save(file);
logger.log(Level.INFO, "Saved merge result to file {0}", file.getAbsolutePath());
} catch (Exception e) {
logger.log(Level.SEVERE, "Failed to write file {0}", file.getAbsolutePath());
}
}
} else {
logger.info("The result is empty");
}
}

private static boolean isBackupFileName(String name){
char c;
int length = name.length();
int i = 0;
if (length!=26){
return false;
}
c = name.charAt(i);
while(i<8 && c>='0' && c<='9'){
i++;
c = name.charAt(i);
}
if (i<8 || c!='_'){
return false;
}
i++;
c = name.charAt(i);
while(i<15 && c>='0' && c<='9'){
i++;
c = name.charAt(i);
}
if (i<15 || c!='_'){
return false;
}
i++;
c = name.charAt(i);
while(i<19 && c>='0' && c<='9'){
i++;
c = name.charAt(i);
}
if (i<19 || c!='.'){
return false;
}

while (i<length-1 && c==".backup".charAt(i-19)){
i++;
c = name.charAt(i);
}
return c==".backup".charAt(i-19);
}

private static File findMostRecentBackupFile(File file) {
final String[] result = new String[1];
file.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
boolean accepted = isBackupFileName(name);
if (accepted && (result[0] == null || name.compareToIgnoreCase(result[0])>0)){
result[0] = name;
}
return accepted;
}
});
if (result[0]!=null){
return new File(file, result[0]);
}
return file;
}
}
42 changes: 42 additions & 0 deletions src/main/java/ru/xibodoh/finmerge/Log.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
~ Copyright (c) 2014-2015 Aleksei Semenov (aka xibodoh)
~ All rights reserved. This program and the accompanying materials
~ are made available under the terms of the GNU Public License v2.0
~ which accompanies this distribution, and is available at
~ http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*/
package ru.xibodoh.finmerge;

import java.util.logging.ConsoleHandler;
import java.util.logging.Formatter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

public class Log {
public static void configure(String level){
Level l = null;
try{
l = Level.parse(level);
} catch (Exception e){
l = Level.INFO;
}
configure(l);
}

public static void configure(Level level){
Logger logger = Logger.getLogger(Log.class.getPackage().getName());
logger.setUseParentHandlers(false);
logger.setLevel(level);
ConsoleHandler consoleHandler = new ConsoleHandler();
consoleHandler.setLevel(Level.ALL);
consoleHandler.setFormatter(new Formatter() {
@Override
public String format(LogRecord record) {
return formatMessage(record)+"\n";
}
});
logger.addHandler(consoleHandler);
}

}
Loading

0 comments on commit 389098f

Please sign in to comment.