Merge branch 'master' into sismics_prod

This commit is contained in:
Benjamin Gamard 2019-01-24 17:38:00 +01:00
commit be236313e9
29 changed files with 447 additions and 115 deletions

View File

@ -4,17 +4,20 @@ language: java
before_install:
- sudo add-apt-repository -y ppa:mc3man/trusty-media
- sudo apt-get -qq update
- sudo apt-get -y -q install ffmpeg mediainfo tesseract-ocr tesseract-ocr-fra tesseract-ocr-ita tesseract-ocr-kor tesseract-ocr-rus tesseract-ocr-ukr tesseract-ocr-spa tesseract-ocr-ara tesseract-ocr-hin tesseract-ocr-deu tesseract-ocr-pol tesseract-ocr-jpn tesseract-ocr-por tesseract-ocr-tha tesseract-ocr-jpn tesseract-ocr-chi-sim tesseract-ocr-chi-tra
- sudo apt-get -y -q install ffmpeg mediainfo tesseract-ocr tesseract-ocr-fra tesseract-ocr-ita tesseract-ocr-kor tesseract-ocr-rus tesseract-ocr-ukr tesseract-ocr-spa tesseract-ocr-ara tesseract-ocr-hin tesseract-ocr-deu tesseract-ocr-pol tesseract-ocr-jpn tesseract-ocr-por tesseract-ocr-tha tesseract-ocr-jpn tesseract-ocr-chi-sim tesseract-ocr-chi-tra tesseract-ocr-nld
- sudo apt-get -y -q install haveged && sudo service haveged start
after_success:
- mvn -Pprod -DskipTests clean install
- docker login -u $DOCKER_USER -p $DOCKER_PASS
- export REPO=sismics/docs
- export TAG=`if [ "$TRAVIS_BRANCH" == "master" ]; then echo "latest"; else echo $TRAVIS_BRANCH ; fi`
- docker build -f Dockerfile -t $REPO:$COMMIT .
- docker tag $REPO:$COMMIT $REPO:$TAG
- docker tag $REPO:$COMMIT $REPO:travis-$TRAVIS_BUILD_NUMBER
- docker push $REPO
- |
if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then
mvn -Pprod -DskipTests clean install
docker login -u $DOCKER_USER -p $DOCKER_PASS
export REPO=sismics/docs
export TAG=`if [ "$TRAVIS_BRANCH" == "master" ]; then echo "latest"; else echo $TRAVIS_BRANCH ; fi`
docker build -f Dockerfile -t $REPO:$COMMIT .
docker tag $REPO:$COMMIT $REPO:$TAG
docker tag $REPO:$COMMIT $REPO:travis-$TRAVIS_BUILD_NUMBER
docker push $REPO
fi
env:
global:
- secure: LRGpjWORb0qy6VuypZjTAfA8uRHlFUMTwb77cenS9PPRBxuSnctC531asS9Xg3DqC5nsRxBBprgfCKotn5S8nBSD1ceHh84NASyzLSBft3xSMbg7f/2i7MQ+pGVwLncusBU6E/drnMFwZBleo+9M8Tf96axY5zuUp90MUTpSgt0=

View File

@ -1,7 +1,7 @@
FROM sismics/ubuntu-jetty:9.4.12
MAINTAINER b.gamard@sismics.com
RUN apt-get update && apt-get -y -q install ffmpeg mediainfo tesseract-ocr tesseract-ocr-fra tesseract-ocr-ita tesseract-ocr-kor tesseract-ocr-rus tesseract-ocr-ukr tesseract-ocr-spa tesseract-ocr-ara tesseract-ocr-hin tesseract-ocr-deu tesseract-ocr-pol tesseract-ocr-jpn tesseract-ocr-por tesseract-ocr-tha tesseract-ocr-jpn tesseract-ocr-chi-sim tesseract-ocr-chi-tra && \
RUN apt-get update && apt-get -y -q install ffmpeg mediainfo tesseract-ocr tesseract-ocr-fra tesseract-ocr-ita tesseract-ocr-kor tesseract-ocr-rus tesseract-ocr-ukr tesseract-ocr-spa tesseract-ocr-ara tesseract-ocr-hin tesseract-ocr-deu tesseract-ocr-pol tesseract-ocr-jpn tesseract-ocr-por tesseract-ocr-tha tesseract-ocr-jpn tesseract-ocr-chi-sim tesseract-ocr-chi-tra tesseract-ocr-nld && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# Remove the embedded javax.mail jar from Jetty

View File

@ -8,6 +8,7 @@
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
android:name=".MainApplication"

View File

@ -33,6 +33,7 @@ public class LanguageAdapter extends BaseAdapter {
}
languageList.add(new Language("fra", R.string.language_french, R.drawable.fra));
languageList.add(new Language("eng", R.string.language_english, R.drawable.eng));
languageList.add(new Language("deu", R.string.language_german, R.drawable.deu));
}
@Override

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1,148 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Validation -->
<string name="validate_error_email">Ungültige E-Mail</string>
<string name="validate_error_length_min">Zu kurz (min. %d)</string>
<string name="validate_error_length_max">Zu lang (max. %d)</string>
<string name="validate_error_required">Erforderlich</string>
<string name="validate_error_alphanumeric">Nur Buchstaben und Zahlen</string>
<!-- App -->
<string name="app_name" translatable="false">Sismics Docs</string>
<string name="drawer_open">Navigationsleiste öffnen</string>
<string name="drawer_close">Navigationsleiste schließen</string>
<string name="login_explain"><![CDATA[Um zu beginnen, müssen Sie Sismics Docs Server herunterladen und installieren <a href="https://github.com/sismics/docs">github.com/sismics/docs</a>, sowie die Login-Daten unten eingeben]]></string>
<string name="server">Server</string>
<string name="username">Username</string>
<string name="password">Password</string>
<string name="login">Login</string>
<string name="ok">OK</string>
<string name="cancel">Abbrechen</string>
<string name="login_fail_title">Login gescheitert</string>
<string name="login_fail">Benutzername oder Passwort falsch</string>
<string name="network_error_title">Netzwerkfehler</string>
<string name="network_error">Netzwerkfehler, überprüfen Sie die Internetverbindung und die Server-URL</string>
<string name="invalid_url_title">Ungültige URL</string>
<string name="invalid_url">Bitte überprüfen Sie die Server-URL und versuchen Sie es erneut</string>
<string name="crash_toast_text">Ein Absturz ist aufgetreten, ein Bericht wurde gesendet, um dieses Problem zu beheben</string>
<string name="created_date">Erstellungsdatum</string>
<string name="download_file">Aktuelle Datei herunterladen</string>
<string name="download_document">Herunterladen</string>
<string name="action_search">Dokumente durchsuchen</string>
<string name="all_documents">Alle Dokumente</string>
<string name="shared_documents">Geteilte Dokumente</string>
<string name="all_tags">Alle Tags</string>
<string name="no_tags">Keine Tags</string>
<string name="error_loading_tags">Fehler beim Laden von Tags</string>
<string name="no_documents">Keine Dokumente</string>
<string name="error_loading_documents">Fehler beim Laden von Dokumenten</string>
<string name="no_files">Keine Dateien</string>
<string name="error_loading_files">Fehler beim Laden von Dateien</string>
<string name="new_document">Neues Dokument</string>
<string name="share">Teilen</string>
<string name="close">Schließen</string>
<string name="add">Hinzufügen</string>
<string name="add_share_hint">Freigabename (optional)</string>
<string name="document_not_shared">Dieses Dokument wird derzeit nicht freigegeben</string>
<string name="delete_share">Diese Freigabe löschen</string>
<string name="send_share">Send this share link</string>
<string name="error_loading_shares">Fehler beim Laden von Freigaben</string>
<string name="error_adding_share">Fehler beim Hinzufügen der Freigabe</string>
<string name="share_default_name">Freigabe Link</string>
<string name="error_deleting_share">Fehler beim Löschen der Freigabe</string>
<string name="send_share_to">Freigabe senden an</string>
<string name="upload_file">Datei hinzufügen</string>
<string name="upload_from">Datei hochladen von</string>
<string name="settings">Einstellungen</string>
<string name="logout">Ausloggen</string>
<string name="version">Version</string>
<string name="build">Build</string>
<string name="pref_advanced_category">Erweiterte Einstellungen</string>
<string name="pref_about_category">Über</string>
<string name="pref_github">GitHub</string>
<string name="pref_issue">Fehler berichten</string>
<string name="pref_clear_cache_title">Cache leeren</string>
<string name="pref_clear_cache_summary">Zwischengespeicherte Dateien löschen</string>
<string name="pref_clear_cache_success">Cache wurde geleert</string>
<string name="pref_clear_history_title">Suchhistorie löschen</string>
<string name="pref_clear_history_summary">Leert die aktuellen Suchvorschläge</string>
<string name="pref_clear_history_success">Suchvorschläge wurden gelöscht</string>
<string name="pref_cache_size">Cache Größe</string>
<string name="language_french" translatable="false">Français</string>
<string name="language_english" translatable="false">English</string>
<string name="language_german" translatable="false">Deutsch</string>
<string name="save">Speichern</string>
<string name="edit_document">Bearbeiten</string>
<string name="error_editing_document">Netzwerkfehler, bitte versuchen Sie es erneut</string>
<string name="please_wait">Bitte warten</string>
<string name="document_editing_message">Daten werden gesendet</string>
<string name="delete_document">Löschen</string>
<string name="delete_document_title">Dokument löschen</string>
<string name="delete_document_message">Dieses Dokument und alle zugehörigen Dateien wirklich löschen?</string>
<string name="document_delete_failure">Netzwerkfehler beim Löschen des Dokuments</string>
<string name="document_deleting_message">Lösche Dokument</string>
<string name="delete_file_title">Datei löschen</string>
<string name="delete_file_message">Die aktuelle Datei wirklich löschen?</string>
<string name="file_delete_failure">Netzwerkfehler beim Löschen der Datei</string>
<string name="file_deleting_message">Lösche Datei</string>
<string name="error_reading_file">Fehler beim Lesen der Datei</string>
<string name="upload_notification_title">Sismics Docs</string>
<string name="upload_notification_message">Neue Datei in das Dokument hochladen</string>
<string name="upload_notification_error">Fehler beim Hochladen der neuen Datei</string>
<string name="delete_file">Aktuelle Datei löschen</string>
<string name="advanced_search">Erweiterte Suche</string>
<string name="search">Suche</string>
<string name="add_tags">Tags hinzufügen</string>
<string name="creation_date">Erstellungsdatum</string>
<string name="description">Beschreibung</string>
<string name="title">Titel</string>
<string name="simple_search">Einfache Suche</string>
<string name="fulltext_search">Volltextsuche</string>
<string name="creator">Ersteller</string>
<string name="after_date">Nach Datum</string>
<string name="before_date">Vor Datum</string>
<string name="search_tags">Tags durchsuchen</string>
<string name="all_languages">Alle Sprachen</string>
<string name="toggle_informations">Informationen anzeigen</string>
<string name="who_can_access">Wer kann darauf zugreifen?</string>
<string name="comments">Kommentare</string>
<string name="no_comments">Keine Kommentare</string>
<string name="error_loading_comments">Fehler beim Laden von Kommentaren</string>
<string name="send">Senden</string>
<string name="add_comment">Kommentar hinzufügen</string>
<string name="comment_add_failure">Fehler beim Hinzufügen des Kommentars</string>
<string name="adding_comment">Füge Kommentar hinzu</string>
<string name="comment_delete">Kommentar löschen</string>
<string name="deleting_comment">Lösche Kommentar</string>
<string name="error_deleting_comment">Fehler beim Löschen des Kommentars</string>
<string name="export_pdf">PDF</string>
<string name="download">Download</string>
<string name="margin">Rand</string>
<string name="fit_image_to_page">Bild an Seite anpassen</string>
<string name="export_comments">Kommentare exportieren</string>
<string name="export_metadata">Metadaten exportieren</string>
<string name="mm">mm</string>
<string name="download_file_title">Sismics Docs Datei Export</string>
<string name="download_document_title">Sismics Docs Dokumentenexport</string>
<string name="download_pdf_title">Sismics Docs PDF Export</string>
<string name="latest_activity">Letzte Aktivität</string>
<string name="activity">Aktivitäten</string>
<string name="email">E-Mail</string>
<string name="storage_quota">Speicherbegrenzung</string>
<string name="storage_display">%1$d/%2$d MB</string>
<string name="validation_code">Validierungscode</string>
<string name="shared">Geteilt</string>
<string name="language">Sprache</string>
<string name="coverage">Geltungsbereich</string>
<string name="type">Typ</string>
<string name="source">Quelle</string>
<string name="format">Format</string>
<string name="publisher">Verleger</string>
<string name="identifier">Identifikator</string>
<string name="subject">Thema</string>
<string name="rights">Rechte</string>
<string name="contributors">Mitwirkende</string>
<string name="relations">Beziehungen</string>
</resources>

View File

@ -71,6 +71,7 @@
<string name="pref_cache_size">Cache size</string>
<string name="language_french" translatable="false">Français</string>
<string name="language_english" translatable="false">English</string>
<string name="language_german" translatable="false">Deutsch</string>
<string name="save">Save</string>
<string name="edit_document">Edit</string>
<string name="error_editing_document">Network error, please try again</string>

View File

@ -38,7 +38,7 @@ public class Constants {
/**
* Supported document languages.
*/
public static final List<String> SUPPORTED_LANGUAGES = Lists.newArrayList("eng", "fra", "ita", "deu", "spa", "por", "pol", "rus", "ukr", "ara", "hin", "chi_sim", "chi_tra", "jpn", "tha", "kor");
public static final List<String> SUPPORTED_LANGUAGES = Lists.newArrayList("eng", "fra", "ita", "deu", "spa", "por", "pol", "rus", "ukr", "ara", "hin", "chi_sim", "chi_tra", "jpn", "tha", "kor", "nld");
/**
* Base URL environment variable.

View File

@ -148,6 +148,8 @@ public class FileDao {
fileDb.setContent(file.getContent());
fileDb.setOrder(file.getOrder());
fileDb.setMimeType(file.getMimeType());
fileDb.setVersionId(file.getVersionId());
fileDb.setLatestVersion(file.isLatestVersion());
return file;
}
@ -180,11 +182,11 @@ public class FileDao {
public List<File> getByDocumentId(String userId, String documentId) {
EntityManager em = ThreadLocalContext.get().getEntityManager();
if (documentId == null) {
Query q = em.createQuery("select f from File f where f.documentId is null and f.deleteDate is null and f.userId = :userId order by f.createDate asc");
Query q = em.createQuery("select f from File f where f.documentId is null and f.deleteDate is null and f.latestVersion = true and f.userId = :userId order by f.createDate asc");
q.setParameter("userId", userId);
return q.getResultList();
}
Query q = em.createQuery("select f from File f where f.documentId = :documentId and f.deleteDate is null order by f.order asc");
Query q = em.createQuery("select f from File f where f.documentId = :documentId and f.latestVersion = true and f.deleteDate is null order by f.order asc");
q.setParameter("documentId", documentId);
return q.getResultList();
}

View File

@ -71,6 +71,24 @@ public class File implements Loggable {
@Column(name = "FIL_ORDER_N")
private Integer order;
/**
* Version ID.
*/
@Column(name = "FIL_IDVERSION_C")
private String versionId;
/**
* Version number (starting at 0).
*/
@Column(name = "FIL_VERSION_N", nullable = false)
private Integer version;
/**
* True if it's the latest version of the file.
*/
@Column(name = "FIL_LATESTVERSION_B", nullable = false)
private boolean latestVersion;
/**
* Private key to decrypt the file.
* Not saved to database, of course.
@ -160,6 +178,33 @@ public class File implements Loggable {
this.privateKey = privateKey;
}
public String getVersionId() {
return versionId;
}
public File setVersionId(String versionId) {
this.versionId = versionId;
return this;
}
public Integer getVersion() {
return version;
}
public File setVersion(Integer version) {
this.version = version;
return this;
}
public boolean isLatestVersion() {
return latestVersion;
}
public File setLatestVersion(boolean latestVersion) {
this.latestVersion = latestVersion;
return this;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)

View File

@ -212,7 +212,7 @@ public class InboxService extends AbstractScheduledService {
}
// Save the document, create the base ACLs
document = DocumentUtil.createDocument(document, "admin");
DocumentUtil.createDocument(document, "admin");
// Add the tag
String tagId = ConfigUtil.getConfigStringValue(ConfigType.INBOX_TAG);
@ -232,7 +232,7 @@ public class InboxService extends AbstractScheduledService {
// Add files to the document
for (EmailUtil.FileContent fileContent : mailContent.getFileContentList()) {
FileUtil.createFile(fileContent.getName(), fileContent.getFile(), fileContent.getSize(),
FileUtil.createFile(fileContent.getName(), null, fileContent.getFile(), fileContent.getSize(),
document.getLanguage(), "admin", document.getId());
}
}

View File

@ -98,6 +98,7 @@ public class FileUtil {
* Create a new file.
*
* @param name File name, can be null
* @param previousFileId ID of the previous version of the file, if the new file is a new version
* @param unencryptedFile Path to the unencrypted file
* @param fileSize File size
* @param language File language, can be null if associated to no document
@ -106,7 +107,7 @@ public class FileUtil {
* @return File ID
* @throws Exception e
*/
public static String createFile(String name, Path unencryptedFile, long fileSize, String language, String userId, String documentId) throws Exception {
public static String createFile(String name, String previousFileId, Path unencryptedFile, long fileSize, String language, String userId, String documentId) throws Exception {
// Validate mime type
String mimeType;
try {
@ -132,22 +133,42 @@ public class FileUtil {
}
}
// Get files of this document
FileDao fileDao = new FileDao();
int order = 0;
if (documentId != null) {
for (File file : fileDao.getByDocumentId(userId, documentId)) {
file.setOrder(order++);
}
}
// Create the file
// Prepare the file
File file = new File();
file.setOrder(order);
file.setOrder(0);
file.setVersion(0);
file.setLatestVersion(true);
file.setDocumentId(documentId);
file.setName(StringUtils.abbreviate(name, 200));
file.setMimeType(mimeType);
file.setUserId(userId);
// Get files of this document
FileDao fileDao = new FileDao();
if (documentId != null) {
if (previousFileId == null) {
// It's not a new version, so put it in last order
file.setOrder(fileDao.getByDocumentId(userId, documentId).size());
} else {
// It's a new version, update the previous version
File previousFile = fileDao.getActiveById(previousFileId);
if (previousFile == null || !previousFile.getDocumentId().equals(documentId)) {
throw new IOException("Previous version mismatch");
}
if (previousFile.getVersionId() == null) {
previousFile.setVersionId(UUID.randomUUID().toString());
}
previousFile.setLatestVersion(false);
file.setVersionId(previousFile.getVersionId());
file.setVersion(previousFile.getVersion() + 1);
fileDao.update(previousFile);
}
}
// Create the file
String fileId = fileDao.create(file, userId);
// Save the file

View File

@ -25,8 +25,7 @@ import org.apache.lucene.document.Field;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.*;
import org.apache.lucene.queryparser.flexible.standard.QueryParserUtil;
import org.apache.lucene.queryparser.flexible.standard.StandardQueryParser;
import org.apache.lucene.queryparser.simple.SimpleQueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
@ -371,29 +370,26 @@ public class LuceneIndexingHandler implements IndexingHandler {
* @throws Exception e
*/
private Map<String, String> search(String searchQuery, String fullSearchQuery) throws Exception {
// Escape query and add quotes so QueryParser generate a PhraseQuery
String escapedSearchQuery = "\"" + QueryParserUtil.escape(searchQuery + " " + fullSearchQuery) + "\"";
String escapedFullSearchQuery = "\"" + QueryParserUtil.escape(fullSearchQuery) + "\"";
// The fulltext query searches in all fields
searchQuery = searchQuery + " " + fullSearchQuery;
// Build search query
Analyzer analyzer = new StandardAnalyzer();
StandardQueryParser qpHelper = new StandardQueryParser(analyzer);
qpHelper.setPhraseSlop(100); // PhraseQuery add terms
// Search on documents and files
BooleanQuery query = new BooleanQuery.Builder()
.add(qpHelper.parse(escapedSearchQuery, "title"), BooleanClause.Occur.SHOULD)
.add(qpHelper.parse(escapedSearchQuery, "description"), BooleanClause.Occur.SHOULD)
.add(qpHelper.parse(escapedSearchQuery, "subject"), BooleanClause.Occur.SHOULD)
.add(qpHelper.parse(escapedSearchQuery, "identifier"), BooleanClause.Occur.SHOULD)
.add(qpHelper.parse(escapedSearchQuery, "publisher"), BooleanClause.Occur.SHOULD)
.add(qpHelper.parse(escapedSearchQuery, "format"), BooleanClause.Occur.SHOULD)
.add(qpHelper.parse(escapedSearchQuery, "source"), BooleanClause.Occur.SHOULD)
.add(qpHelper.parse(escapedSearchQuery, "type"), BooleanClause.Occur.SHOULD)
.add(qpHelper.parse(escapedSearchQuery, "coverage"), BooleanClause.Occur.SHOULD)
.add(qpHelper.parse(escapedSearchQuery, "rights"), BooleanClause.Occur.SHOULD)
.add(qpHelper.parse(escapedSearchQuery, "filename"), BooleanClause.Occur.SHOULD)
.add(qpHelper.parse(escapedFullSearchQuery, "content"), BooleanClause.Occur.SHOULD)
.add(buildQueryParser(analyzer, "title").parse(searchQuery), BooleanClause.Occur.SHOULD)
.add(buildQueryParser(analyzer, "description").parse(searchQuery), BooleanClause.Occur.SHOULD)
.add(buildQueryParser(analyzer, "subject").parse(searchQuery), BooleanClause.Occur.SHOULD)
.add(buildQueryParser(analyzer, "identifier").parse(searchQuery), BooleanClause.Occur.SHOULD)
.add(buildQueryParser(analyzer, "publisher").parse(searchQuery), BooleanClause.Occur.SHOULD)
.add(buildQueryParser(analyzer, "format").parse(searchQuery), BooleanClause.Occur.SHOULD)
.add(buildQueryParser(analyzer, "source").parse(searchQuery), BooleanClause.Occur.SHOULD)
.add(buildQueryParser(analyzer, "type").parse(searchQuery), BooleanClause.Occur.SHOULD)
.add(buildQueryParser(analyzer, "coverage").parse(searchQuery), BooleanClause.Occur.SHOULD)
.add(buildQueryParser(analyzer, "rights").parse(searchQuery), BooleanClause.Occur.SHOULD)
.add(buildQueryParser(analyzer, "filename").parse(searchQuery), BooleanClause.Occur.SHOULD)
.add(buildQueryParser(analyzer, "content").parse(fullSearchQuery), BooleanClause.Occur.SHOULD)
.build();
// Search
@ -435,6 +431,19 @@ public class LuceneIndexingHandler implements IndexingHandler {
return documentMap;
}
/**
* Build a query parser for searching.
*
* @param analyzer Analyzer
* @param field Field
* @return Query parser
*/
private SimpleQueryParser buildQueryParser(Analyzer analyzer, String field) {
SimpleQueryParser simpleQueryParser = new SimpleQueryParser(analyzer, field);
simpleQueryParser.setDefaultOperator(BooleanClause.Occur.MUST); // AND all the terms
return simpleQueryParser;
}
/**
* Build Lucene document from database document.
*

View File

@ -1 +1 @@
db.version=21
db.version=22

View File

@ -0,0 +1,5 @@
alter table T_FILE add column FIL_VERSION_N int not null default 0;
alter table T_FILE add column FIL_LATESTVERSION_B bit not null default 1;
alter table T_FILE add column FIL_IDVERSION_C varchar(36);
update T_CONFIG set CFG_VALUE_C = '22' where CFG_ID_C = 'DB_VERSION';

View File

@ -0,0 +1,10 @@
email.template.password_recovery.subject=Bitte setzen Sie ihr Passwort zur\u00FCck
email.template.password_recovery.hello=Hallo {0}.
email.template.password_recovery.instruction1=Wir haben eine Anfrage zum Zur\u00FCcksetzen Ihres Passworts erhalten.<br/>Wenn Sie keine Hilfe angefordert haben, können Sie diese E-Mail einfach ignorieren.
email.template.password_recovery.instruction2=Um Ihr Passwort zur\u00FCckzusetzen, besuchen Sie bitte den folgenden Link:
email.template.password_recovery.click_here=Klicken Sie hier, um Ihr Passwort zur\u00FCckzusetzen
email.template.route_step_validate.subject=Ein Dokument braucht Ihre Aufmerksamkeit
email.template.route_step_validate.hello=Hallo {0}.
email.template.route_step_validate.instruction1=Ihnen wurde ein Workflow-Schritt zugewiesen, der Ihre Aufmerksamkeit erfordert.
email.template.route_step_validate.instruction2=Um das Dokument anzuzeigen und den Workflow zu \u00FCberpr\u00FCfen, besuchen Sie bitte den folgenden Link:
email.no_html.error=Ihr E-Mail-Client unterst\u00FCtzt keine HTML-Nachrichten

View File

@ -0,0 +1,10 @@
email.template.password_recovery.subject=Bitte setzen Sie ihr Passwort zur\u00FCck
email.template.password_recovery.hello=Hallo {0}.
email.template.password_recovery.instruction1=Wir haben eine Anfrage zum Zur\u00FCcksetzen Ihres Passworts erhalten.<br/>Wenn Sie keine Hilfe angefordert haben, können Sie diese E-Mail einfach ignorieren.
email.template.password_recovery.instruction2=Um Ihr Passwort zur\u00FCckzusetzen, besuchen Sie bitte den folgenden Link:
email.template.password_recovery.click_here=Klicken Sie hier, um Ihr Passwort zur\u00FCckzusetzen
email.template.route_step_validate.subject=Ein Dokument braucht Ihre Aufmerksamkeit
email.template.route_step_validate.hello=Hallo {0}.
email.template.route_step_validate.instruction1=Ihnen wurde ein Workflow-Schritt zugewiesen, der Ihre Aufmerksamkeit erfordert.
email.template.route_step_validate.instruction2=Um das Dokument anzuzeigen und den Workflow zu \u00FCberpr\u00FCfen, besuchen Sie bitte den folgenden Link:
email.no_html.error=Ihr E-Mail-Client unterst\u00FCtzt keine HTML-Nachrichten

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

View File

@ -26,6 +26,25 @@
<artifactId>docs-web-common</artifactId>
</dependency>
<!-- JDK 11 JAXB dependencies -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.0</version>
</dependency>
<!-- Dependencies to Jersey -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>

View File

@ -1,3 +1,3 @@
api.current_version=${project.version}
api.min_version=1.0
db.version=21
db.version=22

View File

@ -900,7 +900,7 @@ public class DocumentResource extends BaseResource {
}
// Save the document, create the base ACLs
document = DocumentUtil.createDocument(document, principal.getId());
DocumentUtil.createDocument(document, principal.getId());
// Raise a document created event
DocumentCreatedAsyncEvent documentCreatedAsyncEvent = new DocumentCreatedAsyncEvent();
@ -911,7 +911,7 @@ public class DocumentResource extends BaseResource {
// Add files to the document
try {
for (EmailUtil.FileContent fileContent : mailContent.getFileContentList()) {
FileUtil.createFile(fileContent.getName(), fileContent.getFile(), fileContent.getSize(),
FileUtil.createFile(fileContent.getName(), null, fileContent.getFile(), fileContent.getSize(),
document.getLanguage(), principal.getId(), document.getId());
}
} catch (IOException e) {

View File

@ -66,6 +66,7 @@ public class FileResource extends BaseResource {
* @apiName PutFile
* @apiGroup File
* @apiParam {String} id Document ID
* @apiParam {String} previousFileId ID of the file to replace by this new version
* @apiParam {String} file File data
* @apiSuccess {String} status Status OK
* @apiSuccess {String} id File ID
@ -88,6 +89,7 @@ public class FileResource extends BaseResource {
@Consumes("multipart/form-data")
public Response add(
@FormDataParam("id") String documentId,
@FormDataParam("previousFileId") String previousFileId,
@FormDataParam("file") FormDataBodyPart fileBodyPart) {
if (!authenticate()) {
throw new ForbiddenClientException();
@ -122,7 +124,7 @@ public class FileResource extends BaseResource {
try {
String name = fileBodyPart.getContentDisposition() != null ?
URLDecoder.decode(fileBodyPart.getContentDisposition().getFileName(), "UTF-8") : null;
String fileId = FileUtil.createFile(name, unencryptedFile, fileSize, documentDto == null ?
String fileId = FileUtil.createFile(name, previousFileId, unencryptedFile, fileSize, documentDto == null ?
null : documentDto.getLanguage(), principal.getId(), documentId);
// Always return OK
@ -392,6 +394,7 @@ public class FileResource extends BaseResource {
* @apiSuccess {String} files.id ID
* @apiSuccess {String} files.mimetype MIME type
* @apiSuccess {String} files.name File name
* @apiSuccess {String} files.version Zero-based version number
* @apiSuccess {String} files.processing True if the file is currently processing
* @apiSuccess {String} files.document_id Document ID
* @apiSuccess {String} files.create_date Create date (timestamp)
@ -433,6 +436,7 @@ public class FileResource extends BaseResource {
.add("id", fileDb.getId())
.add("processing", FileUtil.isProcessingFile(fileDb.getId()))
.add("name", JsonUtil.nullable(fileDb.getName()))
.add("version", fileDb.getVersion())
.add("mimetype", fileDb.getMimeType())
.add("document_id", JsonUtil.nullable(fileDb.getDocumentId()))
.add("create_date", fileDb.getCreateDate().getTime())

View File

@ -507,7 +507,8 @@ angular.module('docs',
{ key: 'chi_tra', label: '繁体中文' },
{ key: 'jpn', label: '日本語' },
{ key: 'tha', label: 'ภาษาไทย' },
{ key: 'kor', label: '한국어' }
{ key: 'kor', label: '한국어' },
{ key: 'nld', label: 'Nederlands' }
];
})
/**

View File

@ -24,8 +24,8 @@
"passwordreset": {
"message": "Bitte geben Sie ein neues Passwort ein.",
"submit": "Mein Passwort ändern",
"error_title": "Fehler beim ändern des Passworts.",
"error_message": "Ihre Anfrage zur Passwort-Wiederherstellung ist abgelaufen, bitte wiederholen Sie die die Anfrage."
"error_title": "Fehler beim Ändern des Passworts.",
"error_message": "Ihre Anfrage zur Passwort-Wiederherstellung ist abgelaufen, bitte wiederholen Sie die Anfrage."
},
"index": {
"toggle_navigation": "Navigation ein-/ausblenden",
@ -36,11 +36,13 @@
"logged_as": "Eingeloggt als {{ username }}",
"nav_settings": "Einstellungen",
"logout": "Logout",
"global_quota_warning": "<strong>Warnung!</strong> Der frei zur Verfügung stehende maximale Speicherplatz ist fast erreicht bei {{ current | number: 0 }}MB ({{ percent | number: 1 }}%) verwendet {{ total | number: 0 }}MB"
"global_quota_warning": "<strong>Warnung!</strong> Der frei zur Verfügung stehende, maximale Speicherplatz ist fast erreicht bei {{ current | number: 0 }}MB ({{ percent | number: 1 }}%) verwendet {{ total | number: 0 }}MB"
},
"document": {
"navigation_up": "Eine Stufe höher",
"toggle_navigation": "Navigation ein-/ausblenden",
"display_mode_list": "Dokumente in Liste anzeigen",
"display_mode_grid": "Dokumente im Raster anzeigen",
"search_simple": "Einfache Suche",
"search_fulltext": "Volltext Suche",
"search_creator": "Urheber",
@ -76,8 +78,8 @@
"type": "Typ",
"coverage": "Geltungsbereich",
"rights": "Rechte",
"relations": "Beziehung",
"page_size": "Seiten Größe",
"relations": "Beziehungen",
"page_size": "Seitengröße",
"page_size_10": "10 pro Seite",
"page_size_20": "20 pro Seite",
"page_size_30": "30 pro Seite",
@ -94,12 +96,12 @@
"shared_document_message": "Sie können dieses Dokument mit diesem Link freigeben. Beachten Sie, dass jeder, der diesen Link hat, das Dokument sehen kann.<br/><input class=\"form-control share-link\" type=\"text\" readonly=\"readonly\" value=\"{{ link }}\" onclick=\"this.select(); document.execCommand('copy');\" />",
"not_found": "Dokument nicht gefunden",
"forbidden": "Zugriff verweigert",
"download_files": "Download Datei",
"download_files": "Datei herunterladen",
"export_pdf": "in PDF exportieren",
"by_creator": "von",
"comments": "Kommentar",
"no_comments": "Noch keine Kommentare zu diesem Dokument vorhanden",
"add_comment": "Fügen sie einen Komentar hinzu",
"add_comment": "Fügen sie einen Kommentar hinzu",
"error_loading_comments": "Fehler beim Laden eines Kommentars",
"workflow_current": "Aktueller Workflow-Status",
"workflow_comment": "Fügen Sie einen Workflow Kommentar hinzu",
@ -111,27 +113,28 @@
"delete_file_message": "Wollen Sie diese Datei wirklich löschen?",
"upload_pending": "Ausstehend...",
"upload_progress": "Hochladen...",
"upload_error": "Fehler beim hochladen",
"upload_error": "Fehler beim Hochladen",
"upload_error_quota": "Maximaler Speicherplatz erreicht",
"drop_zone": "Drag & Drop Dateien hierherziehen, um diese hochzuladen",
"add_files": "Dateien hinzufügen",
"file_processing_indicator": "Diese Datei wird gerade bearbeitet. Die Suche wird nicht verfügbar sein, bevor sie abgeschlossen ist.",
"reprocess_file": "Diese Datei erneut bearbeiten"
"file_processing_indicator": "Diese Datei wird gerade bearbeitet. Die Suche wird nicht verfügbar sein, bevor der Vorgang abgeschlossen ist.",
"reprocess_file": "Diese Datei erneut verarbeiten"
},
"workflow": {
"workflow": "Workflow",
"message": "Verifizieren oder validieren Sie Ihre Dokumente mit Mitarbeitern Ihres Unternehmens mithilfe von Workflows.",
"message": "Verifizieren oder validieren Sie Ihre Dokumente mit Mitarbeitern Ihres Unternehmens mit Hilfe von Workflows.",
"workflow_start_label": "Welcher Workflow soll gestartet werden?",
"add_more_workflow": "Fügen Sie weitere Workflows hinzu",
"start_workflow_submit": "Starten Sie den Workflow",
"full_name": "<strong>{{ name }}</strong> gestartet am {{ create_date | date }}",
"cancel_workflow": "Abbrechen des aktuellen Workflows",
"cancel_workflow_title": "Abbrechen des Workflows",
"cancel_workflow_message": "Wollen Sie den laufenden Workflow wirklich abbrechen?"
"cancel_workflow_message": "Wollen Sie den laufenden Workflow wirklich abbrechen?",
"no_workflow": "Sie können keinen Workflow für dieses Dokument starten."
},
"permissions": {
"permissions": "Berechtigungen",
"message": "Die Berechtigungen können direkt auf dieses Dokument angewendet werden, oder sind erhältlich bei <a href=\"#/tag\">tags</a>.",
"message": "Die Berechtigungen können direkt auf dieses Dokument angewendet werden, oder können von <a href=\"#/tag\">tags</a> vorgegeben werden.",
"title": "Berechtigungen auf diesem Dokument",
"inherited_tags": "Von Tags geerbte Berechtigungen",
"acl_source": "Von",
@ -150,7 +153,7 @@
"primary_metadata": "Primäre Metadaten",
"title_placeholder": "Titel des Dokuments",
"description_placeholder": "Zusammenfassung, Inhaltsverzeichnis oder Freitext",
"new_files": "New files",
"new_files": "neue Dateien",
"orphan_files": "+ {{ count }} Datei{{ count > 1 ? 's' : '' }}",
"additional_metadata": "Weitere Metadaten",
"subject_placeholder": "Schlüsselwörter, abstrakte Sätze oder Klassifizierungscodes",
@ -163,16 +166,16 @@
"default": {
"upload_pending": "Ausstehend...",
"upload_progress": "Lädt hoch...",
"upload_error": "Fehler beim hochladen",
"upload_error": "Fehler beim Hochladen",
"upload_error_quota": "Maximaler Speicherplatz erreicht",
"quick_upload": "Schnelles hochladen",
"quick_upload": "Schnelles Hochladen",
"drop_zone": "Drag & Drop Dateien hierherziehen, um diese hochzuladen",
"add_files": "Dateien hinzufügen",
"add_new_document": "Neues Dokument hinzufügen",
"latest_activity": "Letzte Aktivitäten",
"footer_sismics": "Programmiert mit <span class=\"fas fa-heart\"></span> by <a href=\"https://www.sismics.com\" target=\"_blank\">Sismics</a>",
"footer_sismics": "Programmiert mit <span class=\"fas fa-heart\"></span> von <a href=\"https://www.sismics.com\" target=\"_blank\">Sismics</a>",
"api_documentation": "API Dokumentation",
"feedback": "Geben Sie uns Feedback",
"feedback": "Geben Sie uns Ihr Feedback",
"workflow_document_list": "Mir zugeordnete Dokumente",
"select_all": "Alle auswählen",
"select_none": "Nichts auswählen"
@ -209,7 +212,7 @@
"title": "Tags",
"message_1": "<strong>Tags</strong> sind Kategorien, die den Dokumenten zugeordnet sind.",
"message_2": "Ein Dokument kann mit mehreren Tags versehen werden und ein Tag kann auf mehrere Dokumente angewendet werden.",
"message_3": "Verwendung der <span class=\"glyphicon glyphicon-pencil\"></span> Schaltfläche können Sie die Berechtigungen für ein Tag bearbeiten.",
"message_3": "Unter Verwendung der <span class=\"glyphicon glyphicon-pencil\"></span> Schaltfläche können Sie die Berechtigungen für ein Tag bearbeiten.",
"message_4": "Wenn ein Tag von einem anderen Benutzer oder einer anderen Gruppe gelesen werden kann, können die zugehörigen Dokumente auch von diesen Personen gelesen werden.",
"message_5": "Kennzeichnen Sie z.B. Ihre Firmendokumente mit einem Tag <span class=\"label label-info\">MyCompany</span> und fügen Sie die Berechtigung <strong>Can read</strong> zu einer Gruppe hinzu <span class=\"btn btn-default\">employees</span>"
},
@ -219,7 +222,9 @@
"name": "Name",
"color": "Farbe",
"parent": "Übergeordnet",
"info": "Berechtigungen für dieses Tag werden auch auf Dokumente angewendet, die mit einem Tag versehen sind <span class=\"label label-info\" ng-style=\"{ 'background': color }\">{{ name }}</span>"
"info": "Berechtigungen für dieses Tag werden auch auf Dokumente angewendet, die mit einem Tag versehen sind <span class=\"label label-info\" ng-style=\"{ 'background': color }\">{{ name }}</span>",
"circular_reference_title": "Zirkuläre Referenz",
"circular_reference_message": "Die Hierarchie der übergeordneten Tags bildet eine Schleife. Bitte wählen Sie ein anderes übergeordnetes Tag."
}
},
"group": {
@ -234,7 +239,7 @@
"profile": {
"groups": "Gruppen",
"quota_used": "Benutzter Speicherplatz",
"percent_used": "{{ percent | number: 0 }}% Benutzt",
"percent_used": "{{ percent | number: 0 }}% genutzt",
"related_links": "Weiterführende Links",
"document_created": "Dokumente erstellt von {{ username }}",
"edit_user": "Benutzer {{ username }} bearbeiten"
@ -250,18 +255,18 @@
}
},
"settings": {
"menu_personal_settings": "Peröhnliche Einstellungen",
"menu_personal_settings": "Persönliche Einstellungen",
"menu_user_account": "Benutzerkonto",
"menu_two_factor_auth": "Zwei-Faktor-Authentifizierung",
"menu_opened_sessions": "Geöffnete Sitzung",
"menu_opened_sessions": "Geöffnete Sitzungen",
"menu_file_importer": "Massen Datei Importer",
"menu_general_settings": "Generelle Einstellungen",
"menu_workflow": "Workflow",
"menu_users": "Benutzer",
"menu_groups": "Gruppen",
"menu_vocabularies": "Vokabulare",
"menu_workflow": "Workflows",
"menu_users": "Benutzerverwaltung",
"menu_groups": "Gruppenverwaltung",
"menu_vocabularies": "Vokabulareinträge",
"menu_configuration": "Einstellungen",
"menu_inbox": "Inbox scannen",
"menu_inbox": "Posteingang durchsuchen",
"menu_monitoring": "Überwachung",
"user": {
"title": "Benutzerverwaltung",
@ -290,7 +295,7 @@
}
},
"workflow": {
"title": "Workflow Konfigurator",
"title": "Workflows",
"add_workflow": "Workflow hinzufügen",
"name": "Name",
"create_date": "Erstellungsdatum",
@ -306,22 +311,23 @@
"type_approve": "Genehmigen",
"type_validate": "Bestätigen",
"target": "Zugewiesen an",
"target_help": "<strong>Zulassen:</strong> Überprüfen und fortsetzen des Workflows <br/><strong>Genemigen:</strong> Übernehmen oder lehnen Sie die Überprüfung ab",
"target_help": "<strong>Zulassen:</strong> Überprüfen und fortsetzen des Workflows <br/><strong>Genehmigen:</strong> Übernehmen oder lehnen Sie die Überprüfung ab",
"add_step": "Workflow Schritt hinzufügen",
"actions": "Was passiert danach?",
"remove_action": "Aktion entfernen"
"remove_action": "Aktion entfernen",
"acl_info": "Nur hier definierte Benutzer und Gruppen können diesen Workflow für ein Dokument starten"
}
},
"security": {
"enable_totp": "Zwei-Faktor-Authentifizierung aktivieren",
"enable_totp_message": "Stellen Sie sicher, dass Sie eine TOTP-kompatible Anwendung auf Ihrem Handy haben, die bereit ist, ein neues Konto hinzuzufügen.",
"enable_totp_message": "Stellen Sie sicher, dass Sie eine TOTP-kompatible Anwendung auf Ihrem Telefon haben, die bereit ist, ein neues Konto hinzuzufügen.",
"title": "Zwei-Faktor-Authentifizierung",
"message_1": "Die Zwei-Faktor-Authentifizierung ermöglicht Ihnen eine weitere Abischerung Ihres {{ appName }} Benutzerkontos. Bevor Sie diese Funktion aktivieren, stellen Sie sicher, dass Sie eine TOTP-kompatible Anwendung auf Ihrem Telefon haben:",
"message_1": "Die Zwei-Faktor-Authentifizierung ermöglicht Ihnen eine weitere Absicherung Ihres {{ appName }} Benutzerkontos. Bevor Sie diese Funktion aktivieren, stellen Sie sicher, dass Sie eine TOTP-kompatible Anwendung auf Ihrem Telefon haben:",
"message_google_authenticator": "Für Android, iOS, und Blackberry: <a href=\"https://support.google.com/accounts/answer/1066447\" target=\"_blank\">Google Authenticator</a>",
"message_duo_mobile": "Für Android und iOS: <a href=\"https://guide.duo.com/third-party-accounts\" target=\"_blank\">Duo Mobile</a>",
"message_authenticator": "Für Windows Phone: <a href=\"https://www.microsoft.com/en-US/store/apps/Authenticator/9WZDNCRFJ3RJ\" target=\"_blank\">Authenticator</a>",
"message_2": "Diese Anwendungen generieren automatisch einen Validierungscod der sich nach einer gewissen Zeitspanne ändert. Sie müssen diesen Validierungscode jedes Mal eingeben, wenn Sie sich bei {{ appName }} anmelden. </strong>.",
"secret_key": "Ihr geheimer Schlüssel ist: <strong>{{ secret }}</strong>",
"message_2": "Diese Anwendungen generieren automatisch einen Validierungscode, der sich nach einer gewissen Zeitspanne ändert. Sie müssen diesen Validierungscode jedes Mal eingeben, wenn Sie sich bei {{ appName }} anmelden. </strong>.",
"secret_key": "Ihr geheimer Schlüssel lautet: <strong>{{ secret }}</strong>",
"secret_key_warning": "Konfigurieren Sie Ihre TOTP-App jetzt mit diesem geheimen Schlüssel auf Ihrem Telefon. Sie können später nicht mehr darauf zugreifen.",
"totp_enabled_message": "Die Zwei-Faktor-Authentifizierung ist in Ihrem Konto aktiviert.<br/>Bei jeder Anmeldung auf <strong>{{ appName }}</strong>, werden Sie in Ihrer konfigurierten Telefon-App nach einem Bestätigungscode gefragt.<br/>Wenn Sie Ihr Telefon verlieren, können Sie sich nicht in Ihrem Konto anmelden, aber aktive Sitzungen ermöglichen es Ihnen, einen geheimen Schlüssel neu zu generieren.",
"disable_totp": {
@ -358,7 +364,7 @@
},
"config": {
"title_guest_access": "Gastzugang",
"message_guest_access": "Der Gastzugang ist ein Modus in dem jeder Zugriff hat und {{ appName }} ohne Passwort nutzen kann.<br/>Wie ein normaler Benutzer kann der Gastbenutzer nur auf seine Dokumente zugreifen und Berechtigungen zugreifen.<br/>",
"message_guest_access": "Der Gastzugang ist ein Modus, in dem jeder auf {{appName}} ohne Kennwort zugreifen kann. <br/> Wie ein normaler Benutzer kann der Gastbenutzer nur auf seine Dokumente und diejenigen zugreifen, auf die er über Berechtigungen zugreifen kann.<br/>",
"enable_guest_access": "Gastzugang aktivieren",
"disable_guest_access": "Gastzugang deaktivieren",
"title_theme": "Aussehen anpassen",
@ -371,18 +377,24 @@
"logo": "Logo (quadratische Größe)",
"background_image": "Hintergrundbild",
"uploading_image": "Bild hochladen...",
"title_smtp": "SMTP Email Einstellungen <small>für Passwort wiederherstellung</small",
"title_smtp": "SMTP Email Einstellungen <small>für das Zürucksetzen des Passworts</small>",
"smtp_hostname": "SMTP Server",
"smtp_port": "SMTP Port",
"smtp_from": "Absender E-Mail",
"smtp_username": "SMTP Benutzername",
"smtp_password": "SMTP Passwort",
"smtp_updated": "SMTP Konfiguration erfolgreich aktualisiert"
"smtp_updated": "SMTP Konfiguration erfolgreich aktualisiert",
"webhooks": "Webhooks",
"webhooks_explain": "Webhooks werden aufgerufen, wenn das angegebene Ereignis eintritt. Die angegebene URL wird mit einer JSON-Payload gepostet, die den Ereignisnamen und die ID der betreffenden Ressource enthält.",
"webhook_event": "Ereignisse",
"webhook_url": "URL",
"webhook_create_date": "Erstelldatum",
"webhook_add": "Webhook hinzufügen"
},
"inbox": {
"title": "Posteingang durchsuchen",
"message": "Wenn Sie diese Funktion aktivieren, durchsucht das System den angegebenen Posteingang jede Minute nach <strong>ungelesenen</strong> E-Mails und importieren diese automatisch.<br/>Nach dem Import einer E-Mail wird diese als gelesen markiert.<br/>Folgen Sie den Links zu Konfigurationseinstellungen für <a href=\"https://support.google.com/mail/answer/7126229?hl=en\" target=\"_blank\">Gmail</a>, <a href=\"https://support.office.com/en-us/article/pop-imap-and-smtp-settings-for-outlook-com-d088b986-291d-42b8-9564-9c414e2aa040\" target=\"_blank\">Outlook.com</a>, <a href=\"https://help.yahoo.com/kb/SLN4075.html\" target=\"_blank\">Yahoo</a>.",
"enabled": "Posteingang duchrsuchen aktivieren",
"message": "Wenn Sie diese Funktion aktivieren, durchsucht das System den angegebenen Posteingang jede Minute nach <strong>ungelesenen</strong> E-Mails und importiert diese automatisch.<br/>Nach dem Import einer E-Mail wird diese als gelesen markiert.<br/>Folgen Sie den Links zu Konfigurationseinstellungen für <a href=\"https://support.google.com/mail/answer/7126229?hl=en\" target=\"_blank\">Gmail</a>, <a href=\"https://support.office.com/en-us/article/pop-imap-and-smtp-settings-for-outlook-com-d088b986-291d-42b8-9564-9c414e2aa040\" target=\"_blank\">Outlook.com</a>, <a href=\"https://help.yahoo.com/kb/SLN4075.html\" target=\"_blank\">Yahoo</a>.",
"enabled": "Durchsuchen des Posteingangs aktivieren",
"hostname": "IMAP Server",
"port": "IMAP Port (143 oder 993)",
"username": "IMAP Benutzername",
@ -391,16 +403,21 @@
"test": "Konfiguration testen",
"last_sync": "Letzte Synchronisation: {{ data.date | date: 'medium' }}, {{ data.count }} E-Mail(s){{ data.count > 1 ? 's' : '' }} importiert",
"test_success": "Die Verbindung zum Posteingang war erfolgreich ({{ count }} <strong>unread</strong> message{{ count > 1 ? 's' : '' }})",
"test_fail": "Beim Verbinden mit dem Posteingang ist ein Fehler aufgetreten, bitte überprüfen Sie die Einstellungen"
"test_fail": "Beim Verbinden mit dem Posteingang ist ein Fehler aufgetreten, bitte überprüfen Sie die Einstellungen",
"saved": "IMAP Konfiguration erfolgreich gespeichert"
},
"monitoring": {
"background_tasks": "Hintergrundaufgaben",
"queued_tasks": "Es gibt derzeit {{ count }}} anstehende Tasks.",
"queued_tasks": "Es gibt derzeit {{ count }} anstehende Tasks.",
"queued_tasks_explain": "Dateiverarbeitung, Thumbnail-Erstellung, Index-Update, optische Zeichenerkennung sind Hintergrundaufgaben. Eine große Anzahl unbearbeiteter Aufgaben führt zu unvollständigen Suchergebnissen.",
"server_logs": "Server logs",
"server_logs": "Server Logs",
"log_date": "Datum",
"log_tag": "Tag",
"log_message": "Nachricht"
"log_message": "Nachricht",
"indexing": "Indexierung",
"indexing_info": "Wenn Sie Unstimmigkeiten in den Suchergebnissen feststellen, können Sie versuchen, eine vollständige Neuindizierung durchzuführen. Die Suchergebnisse sind bis zum Abschluss dieser Operation unvollständig.",
"start_reindexing": "Vollständige Neuindizierung starten",
"reindexing_started": "Neuindizierung wurde gestartet, bitte warten Sie, bis es keine Hintergrundaufgaben mehr gibt."
},
"session": {
"title": "Geöffnete Sitzungen",
@ -413,7 +430,7 @@
"clear": "Alle anderen Sitzungen löschen"
},
"vocabulary": {
"title": "Vokabulareinträge",
"title": "Vokabular",
"choose_vocabulary": "Wählen Sie ein Vokabular aus, das Sie bearbeiten möchten.",
"type": "Typ",
"coverage": "Abdeckung",
@ -423,31 +440,31 @@
"new_entry": "Neuer Eintrag"
},
"fileimporter": {
"title": "Massen Datei Importeur",
"title": "Massen Datei Importer",
"advanced_users": "Für fortgeschrittene Benutzer!",
"need_intro": "Wenn Sie:",
"need_1": "Ganze Verzeichnisse von Dateien auf einmal importieren möchten",
"need_2": "Ein Verzeichnis nach neuen Dateien durchsuchen lassen und gefunden Dateien importieren lassen möchten",
"line_1": "Gehen Sie zu <a href=\"https://github.com/sismics/docs/releases\">sismics/docs/releases</a> und laden Sie das Datei-Importer-Tool für Ihr System herunter.",
"line_2": "Folgen Sie dem Link <a href=\"https://github.com/sismics/docs/tree/master/docs-importer\">instructions here</a> um das Import-Toll zu nutzen.",
"line_3": "Ihre Dateien werden in <a href=\"#/document\">Quick upload</a> importiert, danach können Sie die Dateien weiterbearbeiten und Dokumenten zuordnen oder Dokumente erstellen.",
"line_2": "Folgen Sie den <a href=\"https://github.com/sismics/docs/tree/master/docs-importer\">Anweisungen</a>, um das Import-Tool zu nutzen.",
"line_3": "Ihre Dateien werden in <a href=\"#/document\">Modus 'Schnelles Hochladen'</a> importiert. Danach können Sie die Dateien weiterbearbeiten und Dokumenten zuordnen oder Dokumente erstellen.",
"download": "Herunterladen",
"instructions": "Anweisungen"
}
},
"feedback": {
"title": "Geben Sie uns Feedback",
"message": "Irgendwelche Vorschläge oder Fragen zu Sismics Docs? Wir hören Ihnen genre zu!",
"message": "Irgendwelche Vorschläge oder Fragen zu Sismics Docs? Wir hören Ihnen gerne zu!",
"sent_title": "Feedback gesendet",
"sent_message": "Vielen Dank für Ihr Feedback! Es wird uns helfen, Sismics Docs noch besser zu machen."
},
"import": {
"title": "Wird importiert",
"error_quota": "Speicher Limit erreicht, kontaktieren Sie Ihren Administrator, um den Ihnen zur verfügung gestellten Speicherplatz zu erhöhen.",
"error_quota": "Speicherlimit erreicht. Kontaktieren Sie Ihren Administrator, um den Ihnen zur Verfügung gestellten Speicherplatz zu erhöhen.",
"error_general": "Beim Versuch, Ihre Datei zu importieren, ist ein Fehler aufgetreten. Bitte stellen Sie sicher, dass es sich um eine gültige EML-Datei handelt."
},
"app_share": {
"main": "Fragen Sie nach einen Link zu einem gemeinsam genutzten Dokument, um darauf zuzugreifen.",
"main": "Fragen Sie nach einem Link zu einem gemeinsam genutzten Dokument, um darauf zuzugreifen.",
"403": {
"title": "Nicht erlaubt",
"message": "Das Dokument, das Sie anzeigen möchten, ist nicht mehr freigegeben."
@ -458,7 +475,7 @@
"acl_target": "Für",
"acl_permission": "Zugriffsberechtigung",
"add_permission": "Zugriffsberechtigung hinzufügen",
"search_user_group": "Suchen einen Benutzer oder eine Gruppe"
"search_user_group": "Suchen nach einem Benutzer oder einer Gruppe"
},
"auditlog": {
"log_created": "erstellt",
@ -468,7 +485,7 @@
"Comment": "Kommentar",
"Document": "Dokument",
"File": "Datei",
"Group": "Guppe",
"Group": "Gruppe",
"Tag": "Tag",
"User": "Benutzer",
"RouteModel": "Workflow-Muster",
@ -515,13 +532,13 @@
"too_long": "Zu lang",
"email": "Muss eine gültige E-Mailadresse sein",
"password_confirm": "Passwort und Passwortbestätigung müssen übereinstimmen",
"number": "Nummer erfoderlich",
"number": "Nummer erforderlich",
"no_space": "Leerzeichen sind nicht erlaubt"
},
"action_type": {
"ADD_TAG": "Tag hinzufügen",
"REMOVE_TAG": "Tag entfernen",
"PROCESS_FILES": "Dateien bearbeiten"
"PROCESS_FILES": "Dateien verarbeiten"
},
"pagination": {
"previous": "Vorherige",
@ -532,7 +549,7 @@
"ok": "OK",
"cancel": "Abbrechen",
"share": "Teilen",
"unshare": "Nicht mehr Teilen",
"unshare": "Nicht mehr teilen",
"close": "Schliessen",
"add": "Hinzufügen",
"open": "Öffnen",
@ -543,7 +560,7 @@
"delete": "Löschen",
"rename": "Umbenennen",
"loading": "Lädt...",
"send": "Gesendet",
"send": "Absenden",
"enabled": "Aktiviert",
"disabled": "Deaktiviert"
}

View File

@ -1,3 +1,3 @@
api.current_version=${project.version}
api.min_version=1.0
db.version=21
db.version=22

View File

@ -1,3 +1,3 @@
api.current_version=${project.version}
api.min_version=1.0
db.version=21
db.version=22

View File

@ -184,6 +184,7 @@ public class TestDocumentResource extends BaseJerseyTest {
// Search documents
Assert.assertEquals(1, searchDocuments("full:uranium full:einstein", document1Token));
Assert.assertEquals(2, searchDocuments("tit*", document1Token));
Assert.assertEquals(2, searchDocuments("full:title", document1Token));
Assert.assertEquals(2, searchDocuments("title", document1Token));
Assert.assertEquals(1, searchDocuments("super description", document1Token));

View File

@ -140,9 +140,11 @@ public class TestFileResource extends BaseJerseyTest {
Assert.assertEquals(2, files.size());
Assert.assertEquals(file1Id, files.getJsonObject(0).getString("id"));
Assert.assertEquals("PIA00452.jpg", files.getJsonObject(0).getString("name"));
Assert.assertEquals(0, files.getJsonObject(0).getInt("version"));
Assert.assertEquals(163510L, files.getJsonObject(0).getJsonNumber("size").longValue());
Assert.assertEquals(file2Id, files.getJsonObject(1).getString("id"));
Assert.assertEquals("PIA00452.jpg", files.getJsonObject(1).getString("name"));
Assert.assertEquals(0, files.getJsonObject(1).getInt("version"));
// Rename a file
target().path("file/" + file1Id)
@ -225,6 +227,38 @@ public class TestFileResource extends BaseJerseyTest {
target().path("/file/" + file2Id + "/process").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, file1Token)
.post(Entity.form(new Form()), JsonObject.class);
// Add a new version to a file
String file3Id;
try (InputStream is0 = Resources.getResource("file/document.txt").openStream()) {
StreamDataBodyPart streamDataBodyPart = new StreamDataBodyPart("file", is0, "document.txt");
try (FormDataMultiPart multiPart = new FormDataMultiPart()) {
json = target()
.register(MultiPartFeature.class)
.path("/file").request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, file1Token)
.put(Entity.entity(
multiPart
.field("id", document1Id)
.field("previousFileId", file2Id)
.bodyPart(streamDataBodyPart),
MediaType.MULTIPART_FORM_DATA_TYPE), JsonObject.class);
file3Id = json.getString("id");
Assert.assertNotNull(file2Id);
}
}
// Check the newly created version
json = target().path("/file/list")
.queryParam("id", document1Id)
.request()
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, file1Token)
.get(JsonObject.class);
files = json.getJsonArray("files");
Assert.assertEquals(1, files.size());
Assert.assertEquals(file3Id, files.getJsonObject(0).getString("id"));
Assert.assertEquals("document.txt", files.getJsonObject(0).getString("name"));
Assert.assertEquals(1, files.getJsonObject(0).getInt("version"));
}
/**