mirror of
https://github.com/Sheldan/Sissi.git
synced 2026-01-26 19:21:43 +00:00
Compare commits
13 Commits
sissi-1.4.
...
b345fa5502
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b345fa5502 | ||
|
|
d6470e3714 | ||
|
|
b4cebe2b41 | ||
|
|
f3dd85d7d5 | ||
|
|
db318afb2b | ||
|
|
ddd710d1c2 | ||
|
|
81824db1f1 | ||
|
|
0390d7c8ca | ||
|
|
61412f434c | ||
|
|
12e69a18fb | ||
|
|
170ddd9c33 | ||
|
|
de8bbdcbee | ||
|
|
b5bf53fb6a |
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.application</groupId>
|
||||
<artifactId>application</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>executable</artifactId>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi</groupId>
|
||||
<artifactId>sissi</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.application.module.custom</groupId>
|
||||
<artifactId>sissi-customizations</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>application</artifactId>
|
||||
<groupId>dev.sheldan.sissi.application</groupId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.application</groupId>
|
||||
<artifactId>sissi-modules</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
package dev.sheldan.sissi.module.debra.api;
|
||||
|
||||
import dev.sheldan.sissi.module.debra.model.api.*;
|
||||
import dev.sheldan.sissi.module.debra.model.commands.DonationItemModel;
|
||||
import dev.sheldan.sissi.module.debra.model.commands.DonationsModel;
|
||||
import dev.sheldan.sissi.module.debra.service.DonationService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static dev.sheldan.sissi.module.debra.config.DebraFeatureConfig.DEBRA_DONATION_NOTIFICATION_SERVER_ID_ENV_NAME;
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
package dev.sheldan.sissi.module.debra.config;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.ehcache.config.builders.CacheManagerBuilder;
|
||||
import org.ehcache.jsr107.EhcacheCachingProvider;
|
||||
import org.ehcache.jsr107.Eh107Configuration;
|
||||
import org.ehcache.xml.XmlConfiguration;
|
||||
import org.springframework.cache.jcache.JCacheCacheManager;
|
||||
import org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.cache.CacheManager;
|
||||
import javax.cache.Caching;
|
||||
import java.net.URL;
|
||||
|
||||
@Configuration
|
||||
@Slf4j
|
||||
@EnableCaching
|
||||
public class CacheConfig {
|
||||
|
||||
@Bean("donationCacheManager")
|
||||
public JCacheCacheManager jCacheCacheManager() {
|
||||
return new JCacheCacheManager(getDonationCacheManager());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CacheManager getDonationCacheManager() {
|
||||
public JCacheManagerCustomizer cacheManagerCustomizer() {
|
||||
URL myUrl = getClass().getResource("/donation-cache-config.xml");
|
||||
XmlConfiguration xmlConfig = new XmlConfiguration(myUrl);
|
||||
org.ehcache.CacheManager myCacheManager = CacheManagerBuilder.newCacheManager(xmlConfig);
|
||||
EhcacheCachingProvider provider = (EhcacheCachingProvider) Caching.getCachingProvider("org.ehcache.jsr107.EhcacheCachingProvider");
|
||||
|
||||
return provider.getCacheManager(provider.getDefaultURI(), myCacheManager.getRuntimeConfiguration());
|
||||
return cm -> {
|
||||
myCacheManager.getRuntimeConfiguration().getCacheConfigurations().entrySet().forEach(cacheConfiguration -> {
|
||||
javax.cache.configuration.Configuration<?, ?> jConfiguration = Eh107Configuration.fromEhcacheCacheConfiguration(cacheConfiguration.getValue());
|
||||
log.info("Creating custom cache: " + cacheConfiguration.getKey());
|
||||
cm.createCache(cacheConfiguration.getKey(), jConfiguration);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ public class DonationService {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Cacheable(value = "donation-cache", cacheManager = "donationCacheManager")
|
||||
@Cacheable(value = "donation-cache")
|
||||
public DonationsResponse getCachedDonationAmount(Long serverId) {
|
||||
return fetchCurrentDonationAmount(serverId);
|
||||
}
|
||||
@@ -148,10 +148,8 @@ public class DonationService {
|
||||
.build();
|
||||
Response response = okHttpClient.newCall(request).execute();
|
||||
if(!response.isSuccessful()) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.error("Failed to retrieve donation response. Response had code {} with body {}.",
|
||||
response.code(), response.body());
|
||||
}
|
||||
log.error("Failed to retrieve donation response. Response had code {} with body {} and headers {}.",
|
||||
response.code(), response.body().string(), response.headers());
|
||||
throw new DonationAmountNotFoundException();
|
||||
}
|
||||
Gson gson = getGson();
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.application</groupId>
|
||||
<artifactId>sissi-modules</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.application</groupId>
|
||||
<artifactId>application</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.application</groupId>
|
||||
<artifactId>sissi-modules</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>sissi-modules</artifactId>
|
||||
<groupId>dev.sheldan.sissi.application</groupId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@ type: application
|
||||
# This is the chart version. This version number should be incremented each time you make changes
|
||||
# to the chart and its templates, including the app version.
|
||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||
version: 1.4.22
|
||||
version: 1.4.24
|
||||
|
||||
# This is the version number of the application being deployed. This version number should be
|
||||
# incremented each time you make changes to the application. Versions are not expected to
|
||||
# follow Semantic Versioning. They should reflect the version the application is using.
|
||||
# It is recommended to use it with quotes.
|
||||
appVersion: "1.4.22"
|
||||
appVersion: "1.4.24"
|
||||
|
||||
@@ -8,7 +8,7 @@ bot:
|
||||
repository: harbor.sheldan.dev/sissi
|
||||
pullPolicy: IfNotPresent
|
||||
image: sissi-bot
|
||||
tag: 1.4.22
|
||||
tag: 1.4.24
|
||||
livenessProbe:
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 5
|
||||
@@ -25,7 +25,7 @@ restApi:
|
||||
repository: harbor.sheldan.dev/sissi
|
||||
pullPolicy: IfNotPresent
|
||||
image: sissi-rest-api
|
||||
tag: 1.4.20
|
||||
tag: 1.4.24
|
||||
podAnnotations: {}
|
||||
podSecurityContext: {}
|
||||
securityContext: {}
|
||||
@@ -74,7 +74,7 @@ templateDeploymentData:
|
||||
repository: harbor.sheldan.dev/sissi
|
||||
pullPolicy: Always
|
||||
image: sissi-template-data
|
||||
tag: 1.4.22
|
||||
tag: 1.4.24
|
||||
|
||||
dbConfigDeployment:
|
||||
enabled: true
|
||||
@@ -87,7 +87,7 @@ dbConfigDeploymentData:
|
||||
repository: harbor.sheldan.dev/sissi
|
||||
pullPolicy: Always
|
||||
image: sissi-db-data
|
||||
tag: 1.4.22
|
||||
tag: 1.4.24
|
||||
|
||||
dbCredentials:
|
||||
host:
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi</groupId>
|
||||
<artifactId>deployment</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
REGISTRY_PREFIX=harbor.sheldan.dev/sissi/
|
||||
VERSION=1.4.22
|
||||
VERSION=1.4.24
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo "Starting python server..."
|
||||
python3 -u python/main.py
|
||||
cd python && python3 -u main.py
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi</groupId>
|
||||
<artifactId>sissi</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
4
pom.xml
4
pom.xml
@@ -13,7 +13,7 @@
|
||||
<groupId>dev.sheldan.sissi</groupId>
|
||||
<artifactId>sissi</artifactId>
|
||||
<name>Sissi</name>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
@@ -59,7 +59,7 @@
|
||||
<scm>
|
||||
<url>https://maven.pkg.github.com/Sheldan/Sissi</url>
|
||||
<developerConnection>scm:git:git@github.com:Sheldan/Sissi.git</developerConnection>
|
||||
<tag>sissi-1.4.22</tag>
|
||||
<tag>HEAD</tag>
|
||||
</scm>
|
||||
|
||||
</project>
|
||||
217
python/modules/rest-api/debra.py
Normal file
217
python/modules/rest-api/debra.py
Normal file
@@ -0,0 +1,217 @@
|
||||
from flask import request, render_template
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
import requests
|
||||
import os
|
||||
import json
|
||||
import logging
|
||||
from __main__ import app
|
||||
from utils import serve_pil_image
|
||||
|
||||
sissi_host = os.getenv('SISSI_HOST')
|
||||
sissi_port = os.getenv('SISSI_PORT')
|
||||
latest_donations_url = f'http://{sissi_host}:{sissi_port}/debra/latestDonations'
|
||||
highest_donations_url = f'http://{sissi_host}:{sissi_port}/debra/highestDonations'
|
||||
campaign_info_url = f'http://{sissi_host}:{sissi_port}/debra/campaignInfo'
|
||||
|
||||
|
||||
class DonationImageGenerationParameters:
|
||||
validation_message = ''
|
||||
validation_value = ''
|
||||
validated = None
|
||||
|
||||
def __init__(self, font_name, font_size, canvas_width, canvas_height, donation_count, r, g, b):
|
||||
self.font_name = font_name
|
||||
self.font_size = font_size
|
||||
self.canvas_width = canvas_width
|
||||
self.canvas_height = canvas_height
|
||||
self.donation_count = donation_count
|
||||
self.color = (r, g, b)
|
||||
|
||||
def validate(self):
|
||||
self.validated = True
|
||||
if self.font_name not in DonationImageGenerationConstants.allowed_fonts:
|
||||
self.validated = False
|
||||
self.validation_message = f'Font must be one of ' + ','.join(DonationImageGenerationConstants.allowed_fonts)
|
||||
self.validation_value = self.font_name
|
||||
|
||||
if self.font_size > DonationImageGenerationConstants.font_range[1] or self.font_size < DonationImageGenerationConstants.font_range[0]:
|
||||
self.validated = False
|
||||
self.validation_message = f'Font size must be between {DonationImageGenerationConstants.font_range[0]} and {DonationImageGenerationConstants.font_range[1]}'
|
||||
self.validation_value = self.font_size
|
||||
|
||||
if self.canvas_height > DonationImageGenerationConstants.canvas_height_range[1] or self.canvas_height < DonationImageGenerationConstants.canvas_height_range[0]:
|
||||
self.validated = False
|
||||
self.validation_message = f'Canvas height must be between {DonationImageGenerationConstants.canvas_height_range[0]} and {DonationImageGenerationConstants.canvas_height_range[1]}'
|
||||
self.validation_value = self.canvas_height
|
||||
|
||||
if self.canvas_width > DonationImageGenerationConstants.canvas_width_range[1] or self.canvas_width < DonationImageGenerationConstants.canvas_width_range[0]:
|
||||
self.validated = False
|
||||
self.validation_message = f'Canvas width must be between {DonationImageGenerationConstants.canvas_width_range[0]} and {DonationImageGenerationConstants.color_range[1]}'
|
||||
self.validation_value = self.canvas_width
|
||||
|
||||
if self.donation_count > DonationImageGenerationConstants.donation_count_range[1] or self.donation_count < DonationImageGenerationConstants.donation_count_range[0]:
|
||||
self.validated = False
|
||||
self.validation_message = f'Donation count must be between {DonationImageGenerationConstants.donation_count_range[0]} and {DonationImageGenerationConstants.donation_count_range[1]}'
|
||||
self.validation_value = self.donation_count
|
||||
|
||||
if self.color[0] > DonationImageGenerationConstants.color_range[1] or self.color[0] < DonationImageGenerationConstants.color_range[0]:
|
||||
self.validated = False
|
||||
self.validation_message = f'Red must be between {DonationImageGenerationConstants.color_range[0]} and {DonationImageGenerationConstants.color_range[1]} inclusively'
|
||||
self.validation_value = self.color[0]
|
||||
|
||||
if self.color[1] > DonationImageGenerationConstants.color_range[1] or self.color[1] < DonationImageGenerationConstants.color_range[0]:
|
||||
self.validated = False
|
||||
self.validation_message = f'Green must be between {DonationImageGenerationConstants.color_range[0]} and {DonationImageGenerationConstants.color_range[1]} inclusively'
|
||||
self.validation_value = self.color[1]
|
||||
|
||||
if self.color[2] > DonationImageGenerationConstants.color_range[1] or self.color[2] < DonationImageGenerationConstants.color_range[0]:
|
||||
self.validated = False
|
||||
self.validation_message = f'Blue must be between {DonationImageGenerationConstants.color_range[0]} and {DonationImageGenerationConstants.color_range[1]} inclusively'
|
||||
self.validation_value = self.color[2]
|
||||
|
||||
@app.route('/debra/latestDonations')
|
||||
def latest_donations():
|
||||
donation_stats = requests.get(latest_donations_url)
|
||||
logging.info(f'returning latest donations')
|
||||
return donation_stats.text
|
||||
|
||||
|
||||
@app.route('/debra/highestDonations')
|
||||
def highest_donations():
|
||||
donation_stats = requests.get(highest_donations_url)
|
||||
logging.info(f'returning highest donations')
|
||||
return donation_stats.text
|
||||
|
||||
|
||||
@app.route('/debra/campaignInfo')
|
||||
def campaign_info_route():
|
||||
donation_stats = requests.get(campaign_info_url)
|
||||
logging.info(f'returning campaign info')
|
||||
return donation_stats.text
|
||||
|
||||
|
||||
@app.route('/debra/image/help')
|
||||
def show_image_generation_help():
|
||||
|
||||
def make_param(parameters_obj, name, default, values):
|
||||
parameters_obj[name] = {
|
||||
'default': default,
|
||||
'values': values
|
||||
}
|
||||
parameters = {}
|
||||
make_param(parameters, 'font', DonationImageGenerationConstants.font_default, DonationImageGenerationConstants.allowed_fonts)
|
||||
make_param(parameters, 'fontSize', DonationImageGenerationConstants.font_size_default, DonationImageGenerationConstants.font_range)
|
||||
make_param(parameters, 'canvasWidth', DonationImageGenerationConstants.canvas_width_default, DonationImageGenerationConstants.canvas_width_range)
|
||||
make_param(parameters, 'canvasHeight', DonationImageGenerationConstants.canvas_height_default, DonationImageGenerationConstants.canvas_height_range)
|
||||
make_param(parameters, 'donationCount', DonationImageGenerationConstants.donation_count_default, DonationImageGenerationConstants.donation_count_range)
|
||||
make_param(parameters, 'r', DonationImageGenerationConstants.r_default, DonationImageGenerationConstants.color_range)
|
||||
make_param(parameters, 'g', DonationImageGenerationConstants.g_default, DonationImageGenerationConstants.color_range)
|
||||
make_param(parameters, 'b', DonationImageGenerationConstants.b_default, DonationImageGenerationConstants.color_range)
|
||||
info_object = {
|
||||
'parameters': parameters
|
||||
}
|
||||
return json.dumps(info_object)
|
||||
|
||||
|
||||
@app.route('/debra/image/info')
|
||||
def total_donations_image():
|
||||
campaign_info = json.loads(requests.get(campaign_info_url).text)
|
||||
logging.info(f'rendering campaign info')
|
||||
parameters = parse_image_parameters()
|
||||
if not parameters.validated:
|
||||
return parameters.validation_message, 400
|
||||
img = Image.new('RGBA', (parameters.canvas_width, parameters.canvas_height), (255, 0, 0, 0))
|
||||
d1 = ImageDraw.Draw(img)
|
||||
font = ImageFont.truetype(f'{parameters.font_name}.ttf', parameters.font_size)
|
||||
d1.text((0, 0), f"{campaign_info['collected']}/{campaign_info['target']}€", fill=parameters.color, font=font)
|
||||
return serve_pil_image(img)
|
||||
|
||||
|
||||
@app.route('/debra/image/latestDonations')
|
||||
def latest_donation_image():
|
||||
donation_stats = json.loads(requests.get(latest_donations_url).text)
|
||||
logging.info(f'rendering latest donations')
|
||||
parameters = parse_image_parameters()
|
||||
if not parameters.validated:
|
||||
return parameters.validation_message, 400
|
||||
return rendering_donation_image(donation_stats, parameters)
|
||||
|
||||
|
||||
@app.route('/debra/image/highestDonations')
|
||||
def highest_donation_image():
|
||||
donation_stats = json.loads(requests.get(highest_donations_url).text)
|
||||
logging.info(f'rendering highest donations')
|
||||
parameters = parse_image_parameters()
|
||||
if not parameters.validated:
|
||||
return parameters.validation_message, 400
|
||||
return rendering_donation_image(donation_stats, parameters)
|
||||
|
||||
|
||||
@app.route('/debra/image/highestDonations/html')
|
||||
def highest_donations_image_html_wrapper():
|
||||
refresh_interval = int(request.args.get('refreshInterval', 30, type=int))
|
||||
return render_template('image_refresh_wrapper.html', imagePath=f'/debra/image/highestDonations?{request.query_string.decode()}', refreshInterval=refresh_interval)
|
||||
|
||||
|
||||
@app.route('/debra/image/latestDonations/html')
|
||||
def latest_donations_image_html_wrapper():
|
||||
refresh_interval = int(request.args.get('refreshInterval', 30, type=int))
|
||||
return render_template('image_refresh_wrapper.html', imagePath=f'/debra/image/latestDonations?{request.query_string.decode()}', refreshInterval=refresh_interval)
|
||||
|
||||
|
||||
@app.route('/debra/image/info/html')
|
||||
def total_donations_image_html_wrapper():
|
||||
refresh_interval = int(request.args.get('refreshInterval', 30, type=int))
|
||||
return render_template('image_refresh_wrapper.html', imagePath=f'/debra/image/info?{request.query_string.decode()}', refreshInterval=refresh_interval)
|
||||
|
||||
|
||||
def rendering_donation_image(donation_stats, parameters):
|
||||
img = Image.new('RGBA', (parameters.canvas_width, parameters.canvas_height), (255, 0, 0, 0))
|
||||
d1 = ImageDraw.Draw(img)
|
||||
font = ImageFont.truetype(f'{parameters.font_name}.ttf', parameters.font_size)
|
||||
donations_to_draw = donation_stats['donations'][:parameters.donation_count]
|
||||
height = parameters.font_size
|
||||
it = 0
|
||||
for donation in donations_to_draw:
|
||||
name = donation['firstName'] if not donation['anonymous'] else 'anonym'
|
||||
d1.text((0, height * it), f"{donation['donationAmount']}€ von {name}", fill=parameters.color, font=font)
|
||||
it += 1
|
||||
return serve_pil_image(img)
|
||||
|
||||
|
||||
def parse_image_parameters() -> DonationImageGenerationParameters:
|
||||
font = request.args.get('font', DonationImageGenerationConstants.font_default, type=str)
|
||||
font_size = int(request.args.get('fontSize', DonationImageGenerationConstants.font_size_default, type=int))
|
||||
canvas_width = int(request.args.get('canvasWidth', DonationImageGenerationConstants.canvas_width_default, type=int))
|
||||
canvas_height = int(request.args.get('canvasHeight', DonationImageGenerationConstants.canvas_height_default, type=int))
|
||||
donation_count = int(request.args.get('donationCount', DonationImageGenerationConstants.donation_count_default, type=int))
|
||||
r = int(request.args.get('r', DonationImageGenerationConstants.r_default, type=int))
|
||||
g = int(request.args.get('g', DonationImageGenerationConstants.g_default, type=int))
|
||||
b = int(request.args.get('b', DonationImageGenerationConstants.b_default, type=int))
|
||||
parameters = DonationImageGenerationParameters(font, font_size, canvas_width, canvas_height, donation_count, r, g, b)
|
||||
parameters.validate()
|
||||
return parameters
|
||||
|
||||
|
||||
class DonationImageGenerationConstants:
|
||||
allowed_fonts = ['Andale_Mono', 'Courier_New', 'Impact', 'Trebuchet_MS_Italic',
|
||||
'Arial', 'Courier_New_Bold', 'Times_New_Roman', 'Verdana',
|
||||
'Arial_Black', 'Courier_New_Bold_Italic', 'Times_New_Roman_Bold', 'Verdana_Bold',
|
||||
'Arial_Bold', 'Courier_New_Italic', 'Times_New_Roman_Bold_Italic', 'Verdana_Bold_Italic',
|
||||
'Arial_Bold_Italic', 'Georgia', 'Times_New_Roman_Italic', 'Verdana_Italic',
|
||||
'Arial_Italic', 'Georgia_Bold', 'Trebuchet_MS',
|
||||
'Comic_Sans_MS', 'Georgia_Bold_Italic', 'Trebuchet_MS_Bold',
|
||||
'Comic_Sans_MS_Bold', 'Georgia_Italic', 'Trebuchet_MS_Bold_Italic']
|
||||
font_range = (2, 150)
|
||||
canvas_width_range = (1, 2500)
|
||||
canvas_height_range = (1, 2500)
|
||||
donation_count_range = (1, 25)
|
||||
color_range = (0, 255)
|
||||
font_default = 'Arial'
|
||||
font_size_default = 40
|
||||
canvas_width_default = 1024
|
||||
canvas_height_default = 300
|
||||
donation_count_default = 5
|
||||
r_default = 0
|
||||
g_default = 0
|
||||
b_default = 0
|
||||
19
python/modules/rest-api/image_gen.py
Normal file
19
python/modules/rest-api/image_gen.py
Normal file
@@ -0,0 +1,19 @@
|
||||
from __main__ import app
|
||||
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
from flask import request
|
||||
|
||||
from utils import serve_pil_image
|
||||
|
||||
|
||||
@app.route('/memes/doge/orangeSun/')
|
||||
def image_gen():
|
||||
text = request.args.get('text')
|
||||
with Image.open('res/img/semf_template.jpg') as im:
|
||||
d1 = ImageDraw.Draw(im)
|
||||
text_box_size = (300, 240)
|
||||
W, H = text_box_size
|
||||
font = ImageFont.truetype(f'Impact.ttf', 60)
|
||||
_, _, w, h = d1.textbbox((0, 0), text, font=font)
|
||||
d1.text(((W-w)/2 + 320, (H-h)/2 + 120), text, font=font, fill=(255, 255, 255))
|
||||
return serve_pil_image(im)
|
||||
@@ -1,228 +1,22 @@
|
||||
from flask import Flask, send_file, request
|
||||
from io import BytesIO
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
import requests
|
||||
import os
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
|
||||
from flask import Flask
|
||||
|
||||
FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
||||
logging.basicConfig(encoding='utf-8', level=logging.INFO, format=FORMAT)
|
||||
app = Flask(__name__)
|
||||
|
||||
sissi_host = os.getenv('SISSI_HOST')
|
||||
sissi_port = os.getenv('SISSI_PORT')
|
||||
latest_donations_url = f'http://{sissi_host}:{sissi_port}/debra/latestDonations'
|
||||
highest_donations_url = f'http://{sissi_host}:{sissi_port}/debra/highestDonations'
|
||||
campaign_info_url = f'http://{sissi_host}:{sissi_port}/debra/campaignInfo'
|
||||
|
||||
|
||||
class ValidationException(Exception):
|
||||
def __init__(self, provided_value, message):
|
||||
self.provided_value = provided_value
|
||||
self.message = message
|
||||
super().__init__(f'{self.message}: provided value: {provided_value}')
|
||||
|
||||
|
||||
class DonationImageGenerationConstants:
|
||||
allowed_fonts = ['Andale_Mono', 'Courier_New', 'Impact', 'Trebuchet_MS_Italic',
|
||||
'Arial', 'Courier_New_Bold', 'Times_New_Roman', 'Verdana',
|
||||
'Arial_Black', 'Courier_New_Bold_Italic', 'Times_New_Roman_Bold', 'Verdana_Bold',
|
||||
'Arial_Bold', 'Courier_New_Italic', 'Times_New_Roman_Bold_Italic', 'Verdana_Bold_Italic',
|
||||
'Arial_Bold_Italic', 'Georgia', 'Times_New_Roman_Italic', 'Verdana_Italic',
|
||||
'Arial_Italic', 'Georgia_Bold', 'Trebuchet_MS',
|
||||
'Comic_Sans_MS', 'Georgia_Bold_Italic', 'Trebuchet_MS_Bold',
|
||||
'Comic_Sans_MS_Bold', 'Georgia_Italic', 'Trebuchet_MS_Bold_Italic']
|
||||
font_range = (2, 150)
|
||||
canvas_width_range = (1, 2500)
|
||||
canvas_height_range = (1, 2500)
|
||||
donation_count_range = (1, 25)
|
||||
color_range = (0, 255)
|
||||
font_default = 'Arial'
|
||||
font_size_default = 40
|
||||
canvas_width_default = 1024
|
||||
canvas_height_default = 300
|
||||
donation_count_default = 5
|
||||
r_default = 0
|
||||
g_default = 0
|
||||
b_default = 0
|
||||
|
||||
|
||||
class DonationImageGenerationParameters:
|
||||
validation_message = ''
|
||||
validation_value = ''
|
||||
validated = None
|
||||
|
||||
def __init__(self, font_name, font_size, canvas_width, canvas_height, donation_count, r, g, b):
|
||||
self.font_name = font_name
|
||||
self.font_size = font_size
|
||||
self.canvas_width = canvas_width
|
||||
self.canvas_height = canvas_height
|
||||
self.donation_count = donation_count
|
||||
self.color = (r, g, b)
|
||||
|
||||
def validate(self):
|
||||
self.validated = True
|
||||
if self.font_name not in DonationImageGenerationConstants.allowed_fonts:
|
||||
self.validated = False
|
||||
self.validation_message = f'Font must be one of ' + ','.join(DonationImageGenerationConstants.allowed_fonts)
|
||||
self.validation_value = self.font_name
|
||||
|
||||
if self.font_size > DonationImageGenerationConstants.font_range[1] or self.font_size < DonationImageGenerationConstants.font_range[0]:
|
||||
self.validated = False
|
||||
self.validation_message = f'Font size must be between {DonationImageGenerationConstants.font_range[0]} and {DonationImageGenerationConstants.font_range[1]}'
|
||||
self.validation_value = self.font_size
|
||||
|
||||
if self.canvas_height > DonationImageGenerationConstants.canvas_height_range[1] or self.canvas_height < DonationImageGenerationConstants.canvas_height_range[0]:
|
||||
self.validated = False
|
||||
self.validation_message = f'Canvas height must be between {DonationImageGenerationConstants.canvas_height_range[0]} and {DonationImageGenerationConstants.canvas_height_range[1]}'
|
||||
self.validation_value = self.canvas_height
|
||||
|
||||
if self.canvas_width > DonationImageGenerationConstants.canvas_width_range[1] or self.canvas_width < DonationImageGenerationConstants.canvas_width_range[0]:
|
||||
self.validated = False
|
||||
self.validation_message = f'Canvas width must be between {DonationImageGenerationConstants.canvas_width_range[0]} and {DonationImageGenerationConstants.color_range[1]}'
|
||||
self.validation_value = self.canvas_width
|
||||
|
||||
if self.donation_count > DonationImageGenerationConstants.donation_count_range[1] or self.donation_count < DonationImageGenerationConstants.donation_count_range[0]:
|
||||
self.validated = False
|
||||
self.validation_message = f'Donation count must be between {DonationImageGenerationConstants.donation_count_range[0]} and {DonationImageGenerationConstants.donation_count_range[1]}'
|
||||
self.validation_value = self.donation_count
|
||||
|
||||
if self.color[0] > DonationImageGenerationConstants.color_range[1] or self.color[0] < DonationImageGenerationConstants.color_range[0]:
|
||||
self.validated = False
|
||||
self.validation_message = f'Red must be between {DonationImageGenerationConstants.color_range[0]} and {DonationImageGenerationConstants.color_range[1]} inclusively'
|
||||
self.validation_value = self.color[0]
|
||||
|
||||
if self.color[1] > DonationImageGenerationConstants.color_range[1] or self.color[1] < DonationImageGenerationConstants.color_range[0]:
|
||||
self.validated = False
|
||||
self.validation_message = f'Green must be between {DonationImageGenerationConstants.color_range[0]} and {DonationImageGenerationConstants.color_range[1]} inclusively'
|
||||
self.validation_value = self.color[1]
|
||||
|
||||
if self.color[2] > DonationImageGenerationConstants.color_range[1] or self.color[2] < DonationImageGenerationConstants.color_range[0]:
|
||||
self.validated = False
|
||||
self.validation_message = f'Blue must be between {DonationImageGenerationConstants.color_range[0]} and {DonationImageGenerationConstants.color_range[1]} inclusively'
|
||||
self.validation_value = self.color[2]
|
||||
|
||||
template_dir = os.path.abspath('res/templates')
|
||||
app = Flask(__name__, template_folder=template_dir)
|
||||
|
||||
# loads the api end points
|
||||
import debra
|
||||
import image_gen
|
||||
|
||||
@app.route('/')
|
||||
def hello():
|
||||
return 'Hello, World?'
|
||||
|
||||
|
||||
@app.route('/debra/latestDonations')
|
||||
def latest_donations():
|
||||
donation_stats = requests.get(latest_donations_url)
|
||||
logging.info(f'returning latest donations')
|
||||
return donation_stats.text
|
||||
|
||||
|
||||
@app.route('/debra/highestDonations')
|
||||
def highest_donations():
|
||||
donation_stats = requests.get(highest_donations_url)
|
||||
logging.info(f'returning highest donations')
|
||||
return donation_stats.text
|
||||
|
||||
|
||||
@app.route('/debra/campaignInfo')
|
||||
def campaign_info_route():
|
||||
donation_stats = requests.get(campaign_info_url)
|
||||
logging.info(f'returning campaign info')
|
||||
return donation_stats.text
|
||||
|
||||
|
||||
@app.route('/debra/image/help')
|
||||
def show_image_generation_help():
|
||||
|
||||
def make_param(parameters_obj, name, default, values):
|
||||
parameters_obj[name] = {
|
||||
'default': default,
|
||||
'values': values
|
||||
}
|
||||
parameters = {}
|
||||
make_param(parameters, 'font', DonationImageGenerationConstants.font_default, DonationImageGenerationConstants.allowed_fonts)
|
||||
make_param(parameters, 'fontSize', DonationImageGenerationConstants.font_size_default, DonationImageGenerationConstants.font_range)
|
||||
make_param(parameters, 'canvasWidth', DonationImageGenerationConstants.canvas_width_default, DonationImageGenerationConstants.canvas_width_range)
|
||||
make_param(parameters, 'canvasHeight', DonationImageGenerationConstants.canvas_height_default, DonationImageGenerationConstants.canvas_height_range)
|
||||
make_param(parameters, 'donationCount', DonationImageGenerationConstants.donation_count_default, DonationImageGenerationConstants.donation_count_range)
|
||||
make_param(parameters, 'r', DonationImageGenerationConstants.r_default, DonationImageGenerationConstants.color_range)
|
||||
make_param(parameters, 'g', DonationImageGenerationConstants.g_default, DonationImageGenerationConstants.color_range)
|
||||
make_param(parameters, 'b', DonationImageGenerationConstants.b_default, DonationImageGenerationConstants.color_range)
|
||||
info_object = {
|
||||
'parameters': parameters
|
||||
}
|
||||
return json.dumps(info_object)
|
||||
|
||||
|
||||
@app.route('/debra/image/info')
|
||||
def total_donations_image():
|
||||
campaign_info = json.loads(requests.get(campaign_info_url).text)
|
||||
logging.info(f'rendering campaign info')
|
||||
parameters = parse_image_parameters()
|
||||
if not parameters.validated:
|
||||
return parameters.validation_message, 400
|
||||
img = Image.new('RGBA', (parameters.canvas_width, parameters.canvas_height), (255, 0, 0, 0))
|
||||
d1 = ImageDraw.Draw(img)
|
||||
font = ImageFont.truetype(f'{parameters.font_name}.ttf', parameters.font_size)
|
||||
d1.text((0, 0), f"Aktuell {campaign_info['collected']}/{campaign_info['target']}€", fill=parameters.color, font=font)
|
||||
return serve_pil_image(img)
|
||||
|
||||
|
||||
@app.route('/debra/image/latestDonations')
|
||||
def latest_donation_image():
|
||||
donation_stats = json.loads(requests.get(latest_donations_url).text)
|
||||
logging.info(f'rendering latest donations')
|
||||
parameters = parse_image_parameters()
|
||||
if not parameters.validated:
|
||||
return parameters.validation_message, 400
|
||||
return rendering_donation_image(donation_stats, parameters)
|
||||
|
||||
|
||||
@app.route('/debra/image/highestDonations')
|
||||
def highest_donation_image():
|
||||
donation_stats = json.loads(requests.get(highest_donations_url).text)
|
||||
logging.info(f'rendering highest donations')
|
||||
parameters = parse_image_parameters()
|
||||
if not parameters.validated:
|
||||
return parameters.validation_message, 400
|
||||
return rendering_donation_image(donation_stats, parameters)
|
||||
|
||||
|
||||
def rendering_donation_image(donation_stats, parameters):
|
||||
img = Image.new('RGBA', (parameters.canvas_width, parameters.canvas_height), (255, 0, 0, 0))
|
||||
d1 = ImageDraw.Draw(img)
|
||||
font = ImageFont.truetype(f'{parameters.font_name}.ttf', parameters.font_size)
|
||||
donations_to_draw = donation_stats['donations'][:parameters.donation_count]
|
||||
height = parameters.font_size
|
||||
it = 0
|
||||
for donation in donations_to_draw:
|
||||
name = donation['firstName'] if not donation['anonymous'] else 'anonym'
|
||||
d1.text((0, height * it), f"{donation['donationAmount']}€ von {name}", fill=parameters.color, font=font)
|
||||
it += 1
|
||||
return serve_pil_image(img)
|
||||
|
||||
|
||||
def parse_image_parameters() -> DonationImageGenerationParameters:
|
||||
font = request.args.get('font', DonationImageGenerationConstants.font_default)
|
||||
font_size = int(request.args.get('fontSize', DonationImageGenerationConstants.font_size_default))
|
||||
canvas_width = int(request.args.get('canvasWidth', DonationImageGenerationConstants.canvas_width_default))
|
||||
canvas_height = int(request.args.get('canvasHeight', DonationImageGenerationConstants.canvas_height_default))
|
||||
donation_count = int(request.args.get('donationCount', DonationImageGenerationConstants.donation_count_default))
|
||||
r = int(request.args.get('r', DonationImageGenerationConstants.r_default))
|
||||
g = int(request.args.get('g', DonationImageGenerationConstants.g_default))
|
||||
b = int(request.args.get('b', DonationImageGenerationConstants.b_default))
|
||||
parameters = DonationImageGenerationParameters(font, font_size, canvas_width, canvas_height, donation_count, r, g, b)
|
||||
parameters.validate()
|
||||
return parameters
|
||||
|
||||
|
||||
def serve_pil_image(pil_img):
|
||||
img_io = BytesIO()
|
||||
pil_img.save(img_io, 'PNG')
|
||||
img_io.seek(0)
|
||||
return send_file(img_io, mimetype='image/png')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from waitress import serve
|
||||
|
||||
|
||||
BIN
python/modules/rest-api/res/img/semf_template.jpg
Normal file
BIN
python/modules/rest-api/res/img/semf_template.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1,7 @@
|
||||
<meta http-equiv="refresh" content="{{ refreshInterval }}">
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<img src="{{ imagePath }}">
|
||||
</body>
|
||||
</html>
|
||||
17
python/modules/rest-api/utils.py
Normal file
17
python/modules/rest-api/utils.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from io import BytesIO
|
||||
|
||||
from flask import send_file
|
||||
|
||||
|
||||
def serve_pil_image(pil_img):
|
||||
img_io = BytesIO()
|
||||
pil_img.save(img_io, 'PNG')
|
||||
img_io.seek(0)
|
||||
return send_file(img_io, mimetype='image/png')
|
||||
|
||||
|
||||
class ValidationException(Exception):
|
||||
def __init__(self, provided_value, message):
|
||||
self.provided_value = provided_value
|
||||
self.message = message
|
||||
super().__init__(f'{self.message}: provided value: {provided_value}')
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi</groupId>
|
||||
<artifactId>sissi</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.templates</groupId>
|
||||
<artifactId>customization-templates</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>sissi-templates</artifactId>
|
||||
<groupId>dev.sheldan.sissi.templates</groupId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>module-templates</artifactId>
|
||||
<groupId>dev.sheldan.sissi.templates</groupId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>module-templates</artifactId>
|
||||
<groupId>dev.sheldan.sissi.templates</groupId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"embeds": [
|
||||
{
|
||||
<#include "abstracto_color">,
|
||||
<#assign time><@format_instant_date_time instant=meetupTime/></#assign>
|
||||
<#assign time><@format_instant_long_date_time instant=meetupTime/></#assign>
|
||||
<#assign topicText>${topic?json_string}</#assign>
|
||||
"description": "<#include "meetup_cancel_notification_description">"
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"title": {
|
||||
"title": "${topic?json_string}"
|
||||
},
|
||||
"description": "<@format_instant_date_time instant=meetupTime/>
|
||||
"description": "<@format_instant_long_date_time instant=meetupTime/>
|
||||
${description?json_string}"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
{
|
||||
<#include "abstracto_color">,
|
||||
<#assign topicText=meetupTopic>
|
||||
<#assign oldTime><@format_instant_date_time instant=oldDate/></#assign>
|
||||
<#assign newTime><@format_instant_date_time instant=newDate/></#assign>
|
||||
<#assign oldTime><@format_instant_long_date_time instant=oldDate/></#assign>
|
||||
<#assign newTime><@format_instant_long_date_time instant=newDate/></#assign>
|
||||
<#assign messageLink=meetupMessage.jumpUrl>
|
||||
"description": "<@safe_include "changeMeetupTime_notification_text"/>"
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"title": {
|
||||
"title": "${topic?json_string}"
|
||||
},
|
||||
"description": "<@format_instant_date_time instant=meetupTime/>
|
||||
"description": "<@format_instant_long_date_time instant=meetupTime/>
|
||||
${description?json_string}"
|
||||
<#if location?? && location != "%22%22">,
|
||||
"fields": [
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"embeds": [
|
||||
{
|
||||
<#include "abstracto_color">,
|
||||
"description": "<#list meetups as meetup><#assign meetup=meetup><#assign topic=meetup.topic><#assign time><@format_instant_date_time instant=meetup.meetupTime/></#assign><#assign timeRelative><@format_instant_relative instant=meetup.meetupTime/></#assign><#assign link=meetup.meetupMessage.jumpUrl><#include "meetup_list_meetup_display">
|
||||
"description": "<#list meetups as meetup><#assign meetup=meetup><#assign topic=meetup.topic><#assign time><@format_instant_long_date_time instant=meetup.meetupTime/></#assign><#assign timeRelative><@format_instant_relative instant=meetup.meetupTime/></#assign><#assign link=meetup.meetupMessage.jumpUrl><#include "meetup_list_meetup_display">
|
||||
<#else><#include "meetup_list_no_meetups"></#list>"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"title": {
|
||||
"title": "${topic?json_string} - <@safe_include "meetup_message_id_display"/>"
|
||||
},
|
||||
<#assign time><@format_instant_date_time instant=meetupTime/></#assign>
|
||||
<#assign time><@format_instant_long_date_time instant=meetupTime/></#assign>
|
||||
<#assign timeRelative><@format_instant_relative instant=meetupTime/></#assign>
|
||||
<#assign organizerText>${organizer.memberMention}</#assign>
|
||||
<#assign meetupId=meetupId/>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"embeds": [
|
||||
{
|
||||
<#include "abstracto_color">,
|
||||
<#assign time><@format_instant_date_time instant=meetupTime/></#assign>
|
||||
<#assign time><@format_instant_long_date_time instant=meetupTime/></#assign>
|
||||
<#assign topicText>${topic?json_string}</#assign>
|
||||
"description": "<#include "meetup_reminder_notification_description">"
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.templates</groupId>
|
||||
<artifactId>sissi-templates</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.templates</groupId>
|
||||
<artifactId>module-templates</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>module-templates</artifactId>
|
||||
<groupId>dev.sheldan.sissi.templates</groupId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.templates</groupId>
|
||||
<artifactId>templates</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.templates</groupId>
|
||||
<artifactId>template-overrides</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.templates</groupId>
|
||||
<artifactId>template-overrides</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.templates</groupId>
|
||||
<artifactId>template-overrides</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>sissi-templates</artifactId>
|
||||
<groupId>dev.sheldan.sissi.templates</groupId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.templates.translations</groupId>
|
||||
<artifactId>customization-translations</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>sissi-translations</artifactId>
|
||||
<groupId>dev.sheldan.sissi.templates.translations</groupId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>module-translations</artifactId>
|
||||
<groupId>dev.sheldan.sissi.templates.translations</groupId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.templates.translations</groupId>
|
||||
<artifactId>module-translations</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.templates.translations</groupId>
|
||||
<artifactId>sissi-translations</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.templates.translations</groupId>
|
||||
<artifactId>module-translations</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>module-translations</artifactId>
|
||||
<groupId>dev.sheldan.sissi.templates.translations</groupId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.templates</groupId>
|
||||
<artifactId>templates</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.templates.translations.overrides</groupId>
|
||||
<artifactId>translation-overrides</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.templates.translations.overrides</groupId>
|
||||
<artifactId>translation-overrides</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.templates.translations.overrides</groupId>
|
||||
<artifactId>translation-overrides</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.sissi.templates.translations</groupId>
|
||||
<artifactId>sissi-translations</artifactId>
|
||||
<version>1.4.22</version>
|
||||
<version>1.4.25-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user