mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-09 12:31:00 +00:00
Merge branch 'master' into bug4671
This commit is contained in:
commit
cf15a138be
19 files changed
+297
-83
No files matched your search
+10
@@ -9,6 +9,7 @@ import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
|
||||
import com.sap.sailing.datamining.impl.data.ManeuverWithContext;
|
||||
import com.sap.sailing.datamining.impl.data.TrackedLegOfCompetitorWithSpecificTimePointWithContext;
|
||||
import com.sap.sailing.datamining.shared.ManeuverSettings;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
import com.sap.sailing.domain.tracking.ManeuverCurveBoundaries;
|
||||
@@ -36,6 +37,9 @@ public class ManeuverRetrievalProcessor
|
||||
TimePoint finishTime = element.getTrackedLegOfCompetitor().getFinishTime();
|
||||
if (finishTime != null) {
|
||||
Iterable<Maneuver> maneuvers = null;
|
||||
if (!isLastLeg(element)) {
|
||||
finishTime = finishTime.minus(1);
|
||||
}
|
||||
try {
|
||||
maneuvers = element.getTrackedLegOfCompetitor().getManeuvers(finishTime, false);
|
||||
} catch (NoWindException e) {
|
||||
@@ -66,6 +70,12 @@ public class ManeuverRetrievalProcessor
|
||||
return maneuversWithContext;
|
||||
}
|
||||
|
||||
private boolean isLastLeg(HasTrackedLegOfCompetitorContext element) {
|
||||
Waypoint finishWaypoint = element.getTrackedLegContext().getTrackedRaceContext().getRace().getCourse().getLastWaypoint();
|
||||
Waypoint toWaypoint = element.getTrackedLegOfCompetitor().getLeg().getTo();
|
||||
return finishWaypoint.equals(toWaypoint);
|
||||
}
|
||||
|
||||
private boolean isManeuverCompliantWithSettings(Maneuver previousManeuver,
|
||||
ManeuverWithContext currentManeuverWithContext, Maneuver nextManeuver) {
|
||||
boolean mainCurveAnalysis = settings.isMainCurveAnalysis();
|
||||
|
||||
+33
-22
@@ -1,5 +1,9 @@
|
||||
package com.sap.sailing.datamining.impl.data;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.sap.sailing.datamining.Activator;
|
||||
@@ -27,6 +31,7 @@ import com.sap.sailing.domain.tracking.WindPositionMode;
|
||||
import com.sap.sse.common.Distance;
|
||||
import com.sap.sse.common.Speed;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.datamining.data.Cluster;
|
||||
@@ -240,50 +245,56 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext {
|
||||
|
||||
@Override
|
||||
public int getNumberOfManeuvers() {
|
||||
return getNumberOfTacks() + getNumberOfJibes();
|
||||
Set<ManeuverType> maneuverTypes = new HashSet<>();
|
||||
maneuverTypes.add(ManeuverType.TACK);
|
||||
maneuverTypes.add(ManeuverType.JIBE);
|
||||
return getNumberOf(maneuverTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfTacks() {
|
||||
return getNumberOf(ManeuverType.TACK);
|
||||
return getNumberOf(Collections.singleton(ManeuverType.TACK));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfJibes() {
|
||||
return getNumberOf(ManeuverType.JIBE);
|
||||
return getNumberOf(Collections.singleton(ManeuverType.JIBE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfPenaltyCircles() {
|
||||
return getNumberOf(ManeuverType.PENALTY_CIRCLE);
|
||||
return getNumberOf(Collections.singleton(ManeuverType.PENALTY_CIRCLE));
|
||||
}
|
||||
|
||||
private int getNumberOf(ManeuverType maneuverType) {
|
||||
private int getNumberOf(Set<ManeuverType> maneuverTypes) {
|
||||
int number = 0;
|
||||
TrackedRace trackedRace = getTrackedRace();
|
||||
if (trackedRace != null) {
|
||||
TimePoint from = null;
|
||||
TimePoint to = null;
|
||||
Competitor competitor = getCompetitor();
|
||||
Course course = trackedRace.getRace().getCourse();
|
||||
Waypoint startWaypoint = course.getFirstWaypoint();
|
||||
MarkPassing startPassing = trackedRace.getMarkPassing(getCompetitor(), startWaypoint);
|
||||
TimePoint start = startPassing != null ? startPassing.getTimePoint() : trackedRace.getStartOfRace();
|
||||
List<Waypoint> waypoints = Util.createList(course.getWaypoints());
|
||||
|
||||
Waypoint finishWaypoint = course.getLastWaypoint();
|
||||
MarkPassing finishPassing = trackedRace.getMarkPassing(getCompetitor(), finishWaypoint);
|
||||
TimePoint end;
|
||||
if (finishPassing != null) {
|
||||
end = finishPassing.getTimePoint();
|
||||
} else {
|
||||
end = trackedRace.getEndOfRace();
|
||||
if (end == null) {
|
||||
TimePoint endOfTracking = trackedRace.getEndOfTracking();
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
end = endOfTracking != null && endOfTracking.before(now) ? endOfTracking : now;
|
||||
int fromIndex = 0;
|
||||
while (fromIndex < waypoints.size()) {
|
||||
MarkPassing markPassing = trackedRace.getMarkPassing(competitor, waypoints.get(fromIndex));
|
||||
TimePoint passingTime = markPassing != null ? markPassing.getTimePoint() : null;
|
||||
if (passingTime != null) {
|
||||
if (from == null) {
|
||||
from = passingTime;
|
||||
} else {
|
||||
to = passingTime;
|
||||
}
|
||||
}
|
||||
fromIndex++;
|
||||
}
|
||||
|
||||
for (Maneuver maneuver : trackedRace.getManeuvers(getCompetitor(), start, end, false)) {
|
||||
if (maneuver.getType() == maneuverType) {
|
||||
number++;
|
||||
if (from != null && to != null) {
|
||||
for (Maneuver maneuver : trackedRace.getManeuvers(getCompetitor(), from, to, false)) {
|
||||
if (maneuverTypes.contains(maneuver.getType())) {
|
||||
number++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+17
@@ -50,6 +50,7 @@
|
||||
text-align: center;
|
||||
}
|
||||
.regattacompetition_phase_fleetfullwidth .regattacompetition_phase_fleet_race_title {
|
||||
text-overflow: ellipsis;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 1.133333333333333em;
|
||||
@@ -178,3 +179,19 @@
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.regattacompetition_phase_fleetfullwidth, .regattacompetition_phase_fleet_race_title {
|
||||
width: 27%;
|
||||
}
|
||||
|
||||
@media (min-width: 375px) {
|
||||
.regattacompetition_phase_fleetfullwidth, .regattacompetition_phase_fleet_race_title {
|
||||
width: 33%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 700px) {
|
||||
.regattacompetition_phase_fleetfullwidth, .regattacompetition_phase_fleet_race_title {
|
||||
width: 40%;
|
||||
}
|
||||
}
|
||||
+8
-1
@@ -1970,7 +1970,8 @@ windFinderWindSourceTypeName=Windfinder
|
||||
windFinderWindSourceTypeTooltip=Viento medido de uno o más puntos de www.windfinder.com
|
||||
windFinder=Windfinder
|
||||
enterTagsForTheVideo=Indique las etiquetas para el vídeo
|
||||
enterIdOfWindFinderReviewedSpotCollection=Indique el ID de una colección de puntos de Windfinder revisada, por ejemplo "schilksee"
|
||||
enterIdOfWindfinderReviewedSpotCollection=Indique el ID de una colección de puntos de Windfinder revisada, por ejemplo "schilksee"
|
||||
windFinderSpotCollectionsList=Colecciones de puntos de WindFinder
|
||||
enterTagsForTheImage=Indique las etiquetas para la imagen
|
||||
unableToResolveWindFinderSpotId=Imposible resolver el punto Windfinder con ID {0}: {1}
|
||||
windFinderWeatherData=Datos meteorológicos
|
||||
@@ -2063,5 +2064,11 @@ multiUrlChangeSave=Grabar modificaciones de URL
|
||||
multiUrlChangeNewURL=URL nuevo
|
||||
multiUrlNoPrefixWarning=No existe ningún prefijo común, esto significa que normalmente no todos los vídeos seleccionados se alojan actualmente en la misma ubicación. Proceda bajo su propio riesgo.
|
||||
multiUrlChangeExplain=Este diálogo reemplazará en masa las partes comunes al inicio de los URLs del rastreo de medios. Asegúrate de que todas las URL empiezan con el mismo prefijo. Además, eche un vistazo a la nueva columna del URL, y pruebe los URLs resultantes antes de pulsar Grabar.
|
||||
resetZoom=Reinicializar zoom
|
||||
lastEvent=Último evento: {0}
|
||||
teaserOverallLinkToolTip=Para visualizar las series generales, haga clic en la esquina amarilla
|
||||
gender=Sexo
|
||||
manage2SailEventIdBox=ID de evento Manage2Sail
|
||||
manage2SailEventURLBox=URL de evento Manage2Sail (json)
|
||||
manage2SailEventIdBoxTooltip=ID de evento o URL que contiene el ID de evento de Manage2Sail
|
||||
manage2SailPort=Puerto
|
||||
+11
-4
@@ -1851,7 +1851,7 @@ minDataCount=Nombre de données min.
|
||||
moreLoginInformationHeadline=Avantages de SAP Sailing Analytics
|
||||
moreLoginInformationIntroduction=Si vous êtes un utilisateur inscrit sur SAP Sailing Analytics, vous avez accès à des fonctionnalités qui ne sont pas disponibles pour les utilisateurs anonymes. Inscrivez-vous pour accéder à toutes les fonctionnalités indiquées ci-dessous.
|
||||
moreLoginInformationSectionUserSettingsHeading=Options utilisateur
|
||||
moreLoginInformationSectionUserSettingsDescription=Certaines éléments de l''interface utilisateur peuvent être personnalisés. Les fonctionnalités de base sont accessibles à tous les utilisateurs, mais les utilisateurs authentifiés ont la possibilité de modifier leurs options. Celles-ci sont conservées dans leur profil utilisateur et disponibles sur n''importe quel appareil dès que l''utilisateur se connecte.
|
||||
moreLoginInformationSectionUserSettingsDescription=Certains éléments de l''interface utilisateur peuvent être personnalisés. Les fonctionnalités de base sont accessibles à tous les utilisateurs, mais les utilisateurs authentifiés ont la possibilité de modifier leurs options. Celles-ci sont conservées dans leur profil utilisateur et disponibles sur n''importe quel appareil dès que l''utilisateur se connecte.
|
||||
moreLoginInformationSectionStrategySimulatorDescription=Le simulateur permet aux navigateurs de simuler des stratégies sur des portions de parcours grâce à des conditions de vent configurables. Le simulateur se base sur l''ensemble des données historiques disponibles dans SAP Sailing Analytics pour fournir des simulations de comportements de catégories de bateaux spécifiques les plus précises possibles.
|
||||
moreLoginInformationSectionUserNotificationsHeading=Notifications utilisateur
|
||||
moreLoginInformationSectionUserNotificationsDescription=Grâce aux notifications utilisateur, vous pouvez rester informé sur votre catégorie de bateau, votre équipe ou votre concurrent favoris. Vous avez la possibilité de vous abonner afin de recevoir des notifications par e-mail sur votre catégorie de bateau, votre équipe ou votre concurrent favoris, ainsi que sur les différentes courses à venir.
|
||||
@@ -1874,7 +1874,7 @@ maximumSpeedNotFoilingInKnotsTooltip=Vitesse fond maximale en nœuds qu''un bate
|
||||
minimumSpeedForFoilingInKnots=Vitesse fond minimale pour déjauger (nds)
|
||||
minimumSpeedForFoilingInKnotsTooltip=Vitesse fond minimale en nœuds qu''un bateau doit atteindre pour pouvoir déjauger. Si la vitesse est inférieure à celle-ci, la hauteur de planing sera ignorée et le bateau ne sera pas considéré comme étant en déjaugeage. Laissez vide ou indiquez 0 si vous souhaitez également vous référer au capteur de hauteur de planing pour les vitesses faibles.
|
||||
minimumRideHeightInMeters=Hauteur de planing minimale (m)
|
||||
minimumRideHeightInMetersTooltip=Hauteur de planing minimale requise en mètres pour qu''une bateau soit considéré comme étant en état de déjaugeage.
|
||||
minimumRideHeightInMetersTooltip=Hauteur de planing minimale requise en mètres pour qu''un bateau soit considéré comme étant en état de déjaugeage.
|
||||
minimumDurationBetweenAdjacentFoilingSegmentsInSeconds=Durée minimum (s) entre deux tronçons en planing adjacents
|
||||
minimumDurationBetweenAdjacentFoilingSegmentsInSecondsTooltip=Si cette valeur est renseignée et que la durée entre deux tronçons de planing adjacents est inférieure à celle-ci, ces tronçons de planing adjacents seront combinés en un seul.
|
||||
needToProvideValidMinimumRideHeight=Vous devez fournir une valeur de hauteur de planing minimale valide en mètres.
|
||||
@@ -1970,7 +1970,8 @@ windFinderWindSourceTypeName=WindFinder
|
||||
windFinderWindSourceTypeTooltip=Vent mesuré d''un ou plusieurs endroits de www.windfinder.com
|
||||
windFinder=WindFinder
|
||||
enterTagsForTheVideo=Entrez des balises pour la vidéo.
|
||||
enterIdOfWindFinderReviewedSpotCollection=Entrez l''ID d''un ensemble d''endroits WindFinder révisé, par exemple, "Schilksee".
|
||||
enterIdOfWindfinderReviewedSpotCollection=Entrez l''ID d''un ensemble d''endroits WindFinder révisé, par exemple, "Schilksee".
|
||||
windFinderSpotCollectionsList=Ensemble d''endroits WindFinder
|
||||
enterTagsForTheImage=Entrez des balises pour l''image.
|
||||
unableToResolveWindFinderSpotId=Impossible de traiter l''endroit WindFinder ayant l''ID {0} : {1}
|
||||
windFinderWeatherData=Données météo
|
||||
@@ -2063,5 +2064,11 @@ multiUrlChangeSave=Sauvegarder modifications apportées aux URL
|
||||
multiUrlChangeNewURL=Nouvelle URL
|
||||
multiUrlNoPrefixWarning=Aucun préfixe commun n''a été trouvé. Cela signifie généralement que les vidéos sélectionnées ne sont actuellement pas toutes hébergées au même endroit. Vous assumez les risques liés à leur utilisation.
|
||||
multiUrlChangeExplain=Cette boîte de dialogue remplacera en masse les éléments communs au début des URL de piste média. Assurez-vous que toutes les URL commencent par le même préfixe. Veuillez également prendre le temps d''observer la nouvelle colonne d''URL, et de tester les URL résultantes avant de sauvegarder.
|
||||
lastEvent=Dernier événement : {0}
|
||||
resetZoom=Réinitialiser le zoom
|
||||
lastEvent=Dernière manifestation : {0}
|
||||
teaserOverallLinkToolTip=Pour afficher l''ensemble des séries, cliquez sur le coin jaune.
|
||||
gender=Sexe
|
||||
manage2SailEventIdBox=ID de manifestation Manage2Sail
|
||||
manage2SailEventURLBox=URL de la manifestation Manage2Sail (json)
|
||||
manage2SailEventIdBoxTooltip=ID d''événement ou URL contenant l''ID d''événement issu de Manage2Sail
|
||||
manage2SailPort=Bâbord
|
||||
+8
-1
@@ -1970,7 +1970,8 @@ windFinderWindSourceTypeName=Windfinder
|
||||
windFinderWindSourceTypeTooltip=www.windfinder.com の 1 つ以上のスポットから風を測定しました
|
||||
windFinder=Windfinder
|
||||
enterTagsForTheVideo=動画のタグを入力
|
||||
enterIdOfWindFinderReviewedSpotCollection=レビューする Windfinder スポットコレクションの ID を入力 (例: "schilksee")
|
||||
enterIdOfWindfinderReviewedSpotCollection=レビューする Windfinder スポットコレクションの ID を入力 (例: "schilksee")
|
||||
windFinderSpotCollectionsList=WindFinder スポットコレクション
|
||||
enterTagsForTheImage=画像のタグを入力
|
||||
unableToResolveWindFinderSpotId=ID {0} で Windfinder スポットを決定できませんでした: {1}
|
||||
windFinderWeatherData=気象データ
|
||||
@@ -2063,5 +2064,11 @@ multiUrlChangeSave=URL 変更の保存
|
||||
multiUrlChangeNewURL=新規 URL
|
||||
multiUrlNoPrefixWarning=共通の接頭辞が見つかりませんでした。これは通常、選択した動画のうち現在同じ場所に置かれていないものがあることを意味します。自身の責任で進めてください。
|
||||
multiUrlChangeExplain=このダイアログはメディアトラック URL 先頭の共通部分をまとめて置換します。すべての URL が同一の接頭辞で始まっていることを確認してください。また、新規 URL 列を参照し、保存を選択する前に結果として得られる URL を吟味してください。
|
||||
resetZoom=拡大/縮小のリセット
|
||||
lastEvent=最終イベント: {0}
|
||||
teaserOverallLinkToolTip=シリーズ全体を参照するには、黄色になっている隅の部分をクリックしてください
|
||||
gender=性別
|
||||
manage2SailEventIdBox=Manage2Sail イベント ID
|
||||
manage2SailEventURLBox=Manage2Sail イベント URL (JSON)
|
||||
manage2SailEventIdBoxTooltip=イベント ID または Manage2Sail からのイベント ID が入っている URL
|
||||
manage2SailPort=ポート
|
||||
+8
-1
@@ -1970,7 +1970,8 @@ windFinderWindSourceTypeName=WindFinder
|
||||
windFinderWindSourceTypeTooltip=Vento medido de um ou mais locais de www.windfinder.com
|
||||
windFinder=WindFinder
|
||||
enterTagsForTheVideo=Inserir etiquetas para o vídeo
|
||||
enterIdOfWindFinderReviewedSpotCollection=Inserir ID de uma coleção revisada de locais do WindFinder, por exemplo, "schilksee"
|
||||
enterIdOfWindfinderReviewedSpotCollection=Inserir ID de uma coleção revisada de locais do WindFinder, por exemplo, "schilksee"
|
||||
windFinderSpotCollectionsList=Coleções de locais do WindFinder
|
||||
enterTagsForTheImage=Inserir etiquetas para a imagem
|
||||
unableToResolveWindFinderSpotId=Impossível resolver local do WindFinder com ID {0}: {1}
|
||||
windFinderWeatherData=Dados metereológicos
|
||||
@@ -2063,5 +2064,11 @@ multiUrlChangeSave=Gravar modificações do URL
|
||||
multiUrlChangeNewURL=novo URL
|
||||
multiUrlNoPrefixWarning=Não foi encontrado um prefixo comum. Isso normalmente significa que nem todos os vídeos selecionados estão hospedados atualmente no mesmo local. Continue por sua própria conta e risco!
|
||||
multiUrlChangeExplain=Este diálogo irá substituir em massa as partes comuns no início dos URLs da faixa de mídia. Assegure que todos os URLs começam com o mesmo prefixo! Veja também a nova coluna do URL e teste os URLs resultantes antes de pressionar Gravar!
|
||||
resetZoom=Reinicializar zoom
|
||||
lastEvent=Último evento: {0}
|
||||
teaserOverallLinkToolTip=Para ver a série completa, clique no canto amarelo
|
||||
gender=Sexo
|
||||
manage2SailEventIdBox=ID de evento Manage2Sail
|
||||
manage2SailEventURLBox=URL de evento Manage2Sail (json)
|
||||
manage2SailEventIdBoxTooltip=ID de evento ou um URL que contenha o ID de evento do Manage2Sail
|
||||
manage2SailPort=Porta
|
||||
+8
-1
@@ -1970,7 +1970,8 @@ windFinderWindSourceTypeName=WindFinder
|
||||
windFinderWindSourceTypeTooltip=Измерения ветра из одного или нескольких мест www.windfinder.com
|
||||
windFinder=WindFinder
|
||||
enterTagsForTheVideo=Введите теги для видео
|
||||
enterIdOfWindFinderReviewedSpotCollection=Введите ид. просмотренной коллекции мест WindFinder (например, "schilksee")
|
||||
enterIdOfWindfinderReviewedSpotCollection=Введите ид. просмотренной коллекции мест WindFinder (например, "schilksee")
|
||||
windFinderSpotCollectionsList=Коллекции мест WindFinder
|
||||
enterTagsForTheImage=Введите теги для изображения
|
||||
unableToResolveWindFinderSpotId=Не удалось разрешить место WindFinder по ид. {0}: {1}
|
||||
windFinderWeatherData=Данные погоды
|
||||
@@ -2063,5 +2064,11 @@ multiUrlChangeSave=Сохранить изменения URL
|
||||
multiUrlChangeNewURL=Новый URL
|
||||
multiUrlNoPrefixWarning=Общий префикс не найден, это означает, что не все выбранные видео хранятся в одном и том же месте. Можете продолжить на свой риск!
|
||||
multiUrlChangeExplain=В этом диалоговом окне можно выполнить массовую замену общих частей в начале URL объектов мультимедиа. Убедитесь, что все URL имеют одинаковый префикс! Проверьте также столбец с новым URL и протестируйте новые URL перед сохранением!
|
||||
resetZoom=Сбросить увеличение
|
||||
lastEvent=Последнее событие: {0}
|
||||
teaserOverallLinkToolTip=Чтобы увидеть все серии, нажмите желтый треугольник
|
||||
gender=Пол
|
||||
manage2SailEventIdBox=Ид. события Manage2Sail
|
||||
manage2SailEventURLBox=URL события Manage2Sail (json)
|
||||
manage2SailEventIdBoxTooltip=Ид. события или URL, содержащий ид. события из Manage2Sail
|
||||
manage2SailPort=Порт
|
||||
+8
-1
@@ -1970,7 +1970,8 @@ windFinderWindSourceTypeName=WindFinder
|
||||
windFinderWindSourceTypeTooltip=Www.windfinder.com 中一个或多个地点的测量风力
|
||||
windFinder=WindFinder
|
||||
enterTagsForTheVideo=为视频输入标记
|
||||
enterIdOfWindFinderReviewedSpotCollection=输入经检查的 WindFinder 地点集合的编号,例如 "schilksee"
|
||||
enterIdOfWindfinderReviewedSpotCollection=输入经检查的 WindFinder 地点集合的编号,例如 "schilksee"
|
||||
windFinderSpotCollectionsList=WindFinder 地点集合
|
||||
enterTagsForTheImage=为图像输入标记
|
||||
unableToResolveWindFinderSpotId=无法解析编号为{0}的 WindFinder 地点:{1}
|
||||
windFinderWeatherData=天气数据
|
||||
@@ -2063,5 +2064,11 @@ multiUrlChangeSave=保存 URL 更改
|
||||
multiUrlChangeNewURL=新 URL
|
||||
multiUrlNoPrefixWarning=未找到通用前缀,这通常意味着并非所有选定的视频都被托管在当前的相同位置。如继续操作,后果自负!
|
||||
multiUrlChangeExplain=此对话框将在媒体轨道 URL 的起始处批量替换通用部分。确保所有 URL 都以相同的前缀开头!也请注意新的 URL 列,然后在保存之前测试生成的 URL!
|
||||
resetZoom=重置缩放
|
||||
lastEvent=上次活动:{0}
|
||||
teaserOverallLinkToolTip=请查看整体系列赛,请点击黄色角落
|
||||
gender=性别
|
||||
manage2SailEventIdBox=Manage2Sail 活动编号
|
||||
manage2SailEventURLBox=Manage2Sail 活动 URL (json)
|
||||
manage2SailEventIdBoxTooltip=包含 Manage2Sail 中活动编号的活动编号或 URL
|
||||
manage2SailPort=左舷
|
||||
@@ -625,4 +625,23 @@ public class PageObject {
|
||||
}
|
||||
throw new NoAlertPresentException();
|
||||
}
|
||||
|
||||
public boolean isElementEntirelyVisible(WebElement element) {
|
||||
try {
|
||||
if (element.isDisplayed()) {
|
||||
final int windowWidth = driver.manage().window().getSize().getWidth();
|
||||
if (windowWidth >= element.getLocation().x
|
||||
+ element.getSize().width) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// The element may currently only partially visible which makes some of the calls fail
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-32
@@ -2,9 +2,7 @@ package com.sap.sailing.selenium.pages.autoplay;
|
||||
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.support.ui.WebDriverWait;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.sap.sailing.selenium.pages.PageArea;
|
||||
import com.sap.sailing.selenium.pages.leaderboard.LeaderboardTablePO;
|
||||
|
||||
@@ -13,35 +11,9 @@ public class AutoPlayLeaderboardView extends PageArea {
|
||||
super(driver, element);
|
||||
}
|
||||
|
||||
public LeaderboardTablePO getLeaderBoard() {
|
||||
WebElement leaderboardCellTable = new WebDriverWait(driver, 30).until(new Function<WebDriver, WebElement>() {
|
||||
@Override
|
||||
public WebElement apply(WebDriver driver) {
|
||||
WebElement leaderboardCellTable = findElementOrNullBySeleniumId("LeaderboardCellTable");
|
||||
if (leaderboardCellTable != null) {
|
||||
try {
|
||||
if (leaderboardCellTable.isDisplayed()) {
|
||||
final int windowWidth = driver.manage().window().getSize().getWidth();
|
||||
if (windowWidth >= leaderboardCellTable.getLocation().x
|
||||
+ leaderboardCellTable.getSize().width) {
|
||||
return leaderboardCellTable;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// The element may currently only partially visible which makes some of the calls fail
|
||||
// In this case it is necessary to wait for the next loop
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
return new LeaderboardTablePO(this.driver, leaderboardCellTable);
|
||||
public LeaderboardTablePO getLeaderBoardWithData() {
|
||||
LeaderboardTablePO leaderboardTablePO = new LeaderboardTablePO(this.driver, findElementBySeleniumId("LeaderboardCellTable"));
|
||||
leaderboardTablePO.waitForTableToShowData();
|
||||
return leaderboardTablePO;
|
||||
}
|
||||
|
||||
}
|
||||
+18
-4
@@ -4,7 +4,9 @@ import java.io.UnsupportedEncodingException;
|
||||
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.support.ui.WebDriverWait;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.sap.sailing.selenium.core.BySeleniumId;
|
||||
import com.sap.sailing.selenium.core.FindBy;
|
||||
import com.sap.sailing.selenium.pages.HostPage;
|
||||
@@ -21,9 +23,6 @@ public class AutoPlayPage extends HostPage {
|
||||
@FindBy(how = BySeleniumId.class, using = "AutoPlayStartView")
|
||||
private WebElement autoPlayStartView;
|
||||
|
||||
@FindBy(how = BySeleniumId.class, using = "LeaderboardView")
|
||||
private WebElement autoPlayLeaderboardView;
|
||||
|
||||
@FindBy(how = BySeleniumId.class, using = "IdleNextUpView")
|
||||
private WebElement idleNextUpView;
|
||||
|
||||
@@ -76,7 +75,22 @@ public class AutoPlayPage extends HostPage {
|
||||
|
||||
public AutoPlayLeaderboardView goToAutoPlayClassicUrl(WebDriver driver, String url) {
|
||||
driver.get(url); //$NON-NLS-1$
|
||||
return new AutoPlayLeaderboardView(driver, autoPlayLeaderboardView);
|
||||
final WebElement leaderboardViewElement = new WebDriverWait(driver, 30).until(new Function<WebDriver, WebElement>() {
|
||||
@Override
|
||||
public WebElement apply(WebDriver driver) {
|
||||
final WebElement leaderboardViewElement = findElementOrNullBySeleniumId("LeaderboardView");
|
||||
if (leaderboardViewElement != null) {
|
||||
if (isElementEntirelyVisible(leaderboardViewElement)) {
|
||||
return leaderboardViewElement;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
return new AutoPlayLeaderboardView(driver, leaderboardViewElement);
|
||||
}
|
||||
|
||||
public AutoPlayUpcomingView goToAutoPlaySixtyInchUrl(WebDriver webDriver, String url) {
|
||||
|
||||
+11
@@ -11,7 +11,9 @@ import java.util.stream.Stream;
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.support.ui.WebDriverWait;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.sap.sailing.selenium.pages.PageArea;
|
||||
import com.sap.sailing.selenium.pages.common.CSSConstants;
|
||||
|
||||
@@ -343,4 +345,13 @@ public abstract class CellTablePO<T extends DataEntryPO> extends PageArea {
|
||||
|
||||
return LOADING_ANIMATION_IMAGE.equals(image);
|
||||
}
|
||||
|
||||
public void waitForTableToShowData() {
|
||||
new WebDriverWait(driver, 30).until(new Function<WebDriver, Boolean>() {
|
||||
@Override
|
||||
public Boolean apply(WebDriver driver) {
|
||||
return !getRows().isEmpty();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
-13
@@ -7,14 +7,10 @@ import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.NoSuchElementException;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.support.ui.WebDriverWait;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.sap.sailing.selenium.pages.common.CSSHelper;
|
||||
|
||||
import com.sap.sailing.selenium.pages.gwt.CellTablePO;
|
||||
import com.sap.sailing.selenium.pages.gwt.DataEntryPO;
|
||||
|
||||
import com.sap.sailing.selenium.pages.leaderboard.LeaderboardTablePO.LeaderboardEntry;
|
||||
|
||||
public class LeaderboardTablePO extends CellTablePO<LeaderboardEntry> {
|
||||
@@ -195,13 +191,4 @@ public class LeaderboardTablePO extends CellTablePO<LeaderboardEntry> {
|
||||
private WebElement getExpansionButton(WebElement header) {
|
||||
return header.findElement(By.xpath(EXPANSION_BUTTON_XPATH));
|
||||
}
|
||||
|
||||
public void waitForLeaderboardToHaveData() {
|
||||
new WebDriverWait(driver, 30).until(new Predicate<WebDriver>() {
|
||||
@Override
|
||||
public boolean apply(WebDriver driver) {
|
||||
return !getRows().isEmpty();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+24
-3
@@ -12,7 +12,10 @@ import javax.xml.bind.DatatypeConverter;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.support.ui.WebDriverWait;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.sap.sailing.selenium.pages.adminconsole.AdminConsolePage;
|
||||
import com.sap.sailing.selenium.pages.adminconsole.event.EventConfigurationPanelPO;
|
||||
import com.sap.sailing.selenium.pages.adminconsole.leaderboard.LeaderboardConfigurationPanelPO;
|
||||
@@ -117,9 +120,27 @@ public class TestAutoPlay extends AbstractSeleniumTest {
|
||||
assertTrue("Url does not contain proper title " + url, url.contains("lbwh.saph.title=Leaderboard%3A+BMW+Cup+(J80)"));
|
||||
assertTrue("Url does not contain proper name " + url, url.contains("name=BMW+Cup+(J80)"));
|
||||
AutoPlayLeaderboardView autoplayPage = page.goToAutoPlayClassicUrl(getWebDriver(), url);
|
||||
LeaderboardTablePO leaderBoard = autoplayPage.getLeaderBoard();
|
||||
leaderBoard.waitForLeaderboardToHaveData();
|
||||
List<String> races = leaderBoard.getRaceNames();
|
||||
LeaderboardTablePO leaderBoard = autoplayPage.getLeaderBoardWithData();
|
||||
final List<String> races = new WebDriverWait(getWebDriver(), 20).until(new Function<WebDriver, List<String>>() {
|
||||
@Override
|
||||
public List<String> apply(WebDriver arg0) {
|
||||
try {
|
||||
final List<String> races = leaderBoard.getRaceNames();
|
||||
final List<String> result;
|
||||
if (races != null && !races.isEmpty()) {
|
||||
result = races;
|
||||
} else {
|
||||
// The table may seem to be empty while the leaderboard updates itself
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
// While the leaderboard updates its contents, errors may occur while reading data via selenium
|
||||
// In this case we need to try this in the next loop again
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
Assert.assertTrue(races.contains("R1"));
|
||||
Assert.assertTrue(races.contains("R2"));
|
||||
Assert.assertTrue(races.contains("R3"));
|
||||
|
||||
@@ -32,6 +32,19 @@
|
||||
leaving the value empty and confirming the dialog.</li>
|
||||
<li>Up to 15 discards can now be configured for series and leaderboards. This enables, e.g., "Wednesday Night" scenarios
|
||||
where over the season, say, 20 races are run but due to changing participation only, say, the five best ones shall be scored.</li>
|
||||
<li>There is a new scoring scheme available to be selected upon regatta creation.
|
||||
The scoring scheme is named "Low Point System, First with two wins in medals is winner" and introduces the following specifics compared to the standard low point scheme:
|
||||
<ul>
|
||||
<li>Medal series does not feature doubling of points in the medal series by default.</li>
|
||||
<li>A competitor having two wins in the medal series is treated as overall winner.
|
||||
If there is a carry forward column in the medal series, having one point there also counts as a win which means the best competitor in the qualification needs a win less than any other finalist to be the overall winner.</li>
|
||||
<li>If the medal series isn't started yet or no competitor has collected two wins, scoring by points is used.
|
||||
This also applies if the regatta is aborted (e.g. due to weather conditions) before any competitor could win two races in the medal series.</li>
|
||||
<li>If two competitors have the same amount of points in the medal series the tie breaking criteria is the carry forward column of the medal series.
|
||||
If there is no carry forward column in the medal series, the last medal race is used as tie breaking criteria.
|
||||
For any non-medal series, the standard low point rules apply.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="articleSubheadline">June 2018</h2>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
JAVA_HOME=/opt/sapjvm_8
|
||||
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=SAP Sailing Analytics Server
|
||||
Wants=apache2.service
|
||||
After=network.target apache2.service
|
||||
|
||||
[Service]
|
||||
User=sailing
|
||||
Group=sailing
|
||||
EnvironmentFile=-/home/sailing/environment
|
||||
EnvironmentFile=-/home/sailing/servers/%i/environment
|
||||
WorkingDirectory=/home/sailing/servers/%i
|
||||
ExecStart=/home/sailing/start_foreground
|
||||
Restart=on-failure
|
||||
Executable
+83
@@ -0,0 +1,83 @@
|
||||
#!/bin/bash
|
||||
|
||||
# source variables
|
||||
if [ "$TMP" = "" ]; then
|
||||
TMP=/tmp
|
||||
fi
|
||||
|
||||
source "env.sh"
|
||||
|
||||
# make some checks
|
||||
JAVA_BINARY="$JAVA_HOME/bin/java"
|
||||
if [[ ! -x "$JAVA_BINARY" ]]
|
||||
then
|
||||
echo "java not found" 1>&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if netstat -tlnp 2>/dev/null | grep ":$SERVER_PORT" >/dev/null
|
||||
then
|
||||
echo "There is something already running on port $SERVER_PORT. Perhaps your server that has not been stopped?" 1>&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
scriptdir="$(dirname "$(readlink -f "$0")")"
|
||||
LIB_DIR="$(pwd)/native-libraries"
|
||||
|
||||
if [[ ! -d "logs" ]]; then
|
||||
mkdir logs
|
||||
fi
|
||||
|
||||
if [[ ! -d "tmp" ]]; then
|
||||
mkdir tmp
|
||||
fi
|
||||
|
||||
echo "Script directory is $scriptdir and LIB_DIR is $LIB_DIR"
|
||||
|
||||
# Make really sure that parameters from config.ini are not used
|
||||
sed -i "/mongo.host/d" ./configuration/config.ini
|
||||
sed -i "/mongo.port/d" ./configuration/config.ini
|
||||
sed -i "/expedition.udp.port/d" ./configuration/config.ini
|
||||
sed -i "/replication.exchangeName/d" ./configuration/config.ini
|
||||
sed -i "/replication.exchangeHost/d" ./configuration/config.ini
|
||||
|
||||
# Ensure that Jetty Port is set correctly
|
||||
sed -i "s/^.*jetty.http.port.*$/<Set name=\"port\"><Property name=\"jetty.http.port\" deprecated=\"jetty.port\" default=\"$SERVER_PORT\"\/><\/Set>/g" ./configuration/jetty/etc/jetty-http.xml
|
||||
|
||||
# Update monitoring with the right ports
|
||||
sed -i "s/127.0.0.1:[0-9][0-9][0-9][0-9]\//127.0.0.1:$SERVER_PORT\//g" ./configuration/monitoring.properties
|
||||
|
||||
# Inject information for system
|
||||
HEAD_DATE=$(date "+%Y%m%d%H%M")
|
||||
sed -i "s/System:.*$/ System: $MONGODB_HOST:$MONGODB_PORT\/$MONGODB_NAME-$EXPEDITION_PORT-$REPLICATION_HOST:$REPLICATION_PORT\/$REPLICATION_CHANNEL Started: $HEAD_DATE/g" ./configuration/jetty/version.txt
|
||||
|
||||
props=(
|
||||
-D$SERVER_NAME
|
||||
-Djava.awt.headless=true
|
||||
-Dcom.sap.sailing.server.name=$SERVER_NAME
|
||||
-Dmongo.host="$MONGODB_HOST"
|
||||
-Dmongo.port="$MONGODB_PORT"
|
||||
-Dmongo.dbName="$MONGODB_NAME"
|
||||
-Dexpedition.udp.port="$EXPEDITION_PORT"
|
||||
-Dreplication.exchangeHost="$REPLICATION_HOST"
|
||||
-Dreplication.exchangePort="$REPLICATION_PORT"
|
||||
-Dreplication.exchangeName="$REPLICATION_CHANNEL"
|
||||
-Dreplicate.on.start="$REPLICATE_ON_START"
|
||||
-Dreplicate.master.servlet.host="$REPLICATE_MASTER_SERVLET_HOST"
|
||||
-Dreplicate.master.servlet.port="$REPLICATE_MASTER_SERVLET_PORT"
|
||||
-Dreplicate.master.queue.host="$REPLICATE_MASTER_QUEUE_HOST"
|
||||
-Dreplicate.master.queue.port="$REPLICATE_MASTER_QUEUE_PORT"
|
||||
-Dreplicate.master.exchange.name="$REPLICATE_MASTER_EXCHANGE_NAME"
|
||||
-Djava.io.tmpdir="$PWD/tmp"
|
||||
-Dfile.encoding=cp1252
|
||||
-Djetty.home=$scriptdir/configuration/jetty
|
||||
-Djava.util.logging.config.file=$scriptdir/configuration/logging.properties
|
||||
-Djava.library.path=$LIB_DIR
|
||||
-Dosgi.shell.telnet.port=$TELNET_PORT
|
||||
)
|
||||
|
||||
jar="plugins/org.eclipse.equinox.launcher_1.3.0.v20140415-2008.jar"
|
||||
args=(-configuration ./ -clean)
|
||||
|
||||
"$JAVA_BINARY" "${props[@]}" $ADDITIONAL_JAVA_ARGS -Xmx$MEMORY -jar "$jar" "${args[@]}"
|
||||
|
||||
Reference in new issue
Block a user