mirror of
https://framagit.org/fiat-tux/hat-softwares/lutim.git
synced 2026-03-28 17:42:54 +01:00
Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ebf9f66e47 | ||
|
|
ed70fbac2e | ||
|
|
af11a1e7ec | ||
|
|
438ce5050e | ||
|
|
d67d66d0fd | ||
|
|
cc03ba6d3f | ||
|
|
5b4f56b9f6 | ||
|
|
8b6766f498 | ||
|
|
68518dd85c | ||
|
|
e7d0821cff | ||
|
|
121c00167c | ||
|
|
c3c3c7a780 | ||
|
|
47a67a428d | ||
|
|
a9b514a30c | ||
|
|
680b3d7057 | ||
|
|
18888c05b3 | ||
|
|
d0e472fe95 | ||
|
|
10f1bd58c5 | ||
|
|
34be40d928 | ||
|
|
e7d87dac3c | ||
|
|
2bff3fcc51 | ||
|
|
c0da308963 | ||
|
|
8515a2b2c7 | ||
|
|
3dc46ebad5 | ||
|
|
c5a69e6128 | ||
|
|
45b8e6c3e2 | ||
|
|
8c40ae36bc | ||
|
|
6b5e52fba3 | ||
|
|
5db403f040 | ||
|
|
3a0f39761c | ||
|
|
691e0c3592 | ||
|
|
8e4f6c7b22 | ||
|
|
21b592cb51 | ||
|
|
c15f6dea68 | ||
|
|
c9a5cfdcd4 | ||
|
|
e4d78e5433 | ||
|
|
bb6b0c30a8 | ||
|
|
a46aab6ffa | ||
|
|
f610608aa1 | ||
|
|
52b436657f | ||
|
|
4486b32da5 | ||
|
|
17c862ae19 | ||
|
|
124ca306b4 | ||
|
|
7d845b9e64 | ||
|
|
3dd1fdca56 | ||
|
|
87efb615bb | ||
|
|
e17a51d8d5 | ||
|
|
c40d22427a | ||
|
|
4384bd1b9f |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -15,6 +15,8 @@ themes/default/templates/data.html.ep
|
||||
themes/default/templates/raw.html.ep
|
||||
themes/default/templates/stats.json.ep
|
||||
themes/default/templates/partial/raw.js.ep
|
||||
!themes/korrigan
|
||||
!themes/korrigan/*
|
||||
tmp/*
|
||||
.zanata-cache/*
|
||||
cover_db/*
|
||||
|
||||
@@ -86,6 +86,7 @@ carton:
|
||||
- local/
|
||||
dependencies: []
|
||||
script:
|
||||
- cpanm -l local Devel::Cover~1.29
|
||||
- carton install --deployment --without=sqlite --without=postgresql --without=minion --without=cache --without=memcached
|
||||
when: always
|
||||
|
||||
|
||||
7
.provision/README.md
Normal file
7
.provision/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
## ansible-role-lutim
|
||||
|
||||
An ansible role deploy the application on host machine(Ubuntu 20.04)
|
||||
|
||||
## terraform-aws-lutim
|
||||
|
||||
A terraform plan creates necessary AWS infrastructure and deploy the lutim. This terraform plan uses the `lutim_startup.sh` script to deploy lufi on AWS and also uses above ansible role `ansible-role-lutim` to configure the application on AWS.
|
||||
50
.provision/ansible-role-lutim/README.md
Normal file
50
.provision/ansible-role-lutim/README.md
Normal file
@@ -0,0 +1,50 @@
|
||||
Ansible-Role-lutim
|
||||
=========
|
||||
This role installs the and configures lutim on Debian/Ubuntu servers with nginx web server configuration.
|
||||
|
||||
Role Variables
|
||||
--------------
|
||||
| Variable name | Value | Description |
|
||||
| ------------- | ----- | ----------- |
|
||||
| `app_dir` | /var/www/lutim | Set the application directory for the best practice |
|
||||
| `lutim_owner` | www-data | Set the application user for the best practice |
|
||||
| `lutim_group` | www-data | Set the application group for the best practice |
|
||||
| `_contact` | contact.example.com | Contact option (mandatory), where you have to put some way for the users to contact you. |
|
||||
| `_secrets` | ffyg7kbkjba | Secrets option (mandotory), which is array of random string. Used by Mojolicious for encrypting session cookies |
|
||||
| `_project_version` | master | We can chose the project version either Master branch, Dev branch or tag based |
|
||||
| `_server_name` | IP address (or) CNAME/FQDN | Mention the Server Name for the Nginx configurations |
|
||||
|
||||
Sample example of use in a playbook
|
||||
--------------
|
||||
|
||||
The following code has been tested with Ubuntu 20.04
|
||||
|
||||
```yaml
|
||||
|
||||
- name: "install lutim"
|
||||
hosts: enter your hosts file
|
||||
become: yes
|
||||
role:
|
||||
- ansible-role-lutim
|
||||
vars:
|
||||
lutim_owner: "www-data"
|
||||
lutim_group: "www-data"
|
||||
contact: "contact.example.com"
|
||||
secrets: "yigavlvlivwe"
|
||||
app_dir: "/var/www/lutim"
|
||||
project_version: "master"
|
||||
servername: "IP address (or) CNAME/FQDN"
|
||||
```
|
||||
|
||||
Contributing
|
||||
------------
|
||||
Don’t hesitate to create a pull request
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
6
.provision/ansible-role-lutim/files/cronjob
Normal file
6
.provision/ansible-role-lutim/files/cronjob
Normal file
@@ -0,0 +1,6 @@
|
||||
#Path of the script
|
||||
PATH=/var/www/lutim
|
||||
|
||||
carton exec script/lutim cron cleanbdd --mode production
|
||||
carton exec script/lutim cron cleanfiles --mode production
|
||||
carton exec script/lutim cron watch --mode production
|
||||
5
.provision/ansible-role-lutim/handlers/main.yml
Normal file
5
.provision/ansible-role-lutim/handlers/main.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
# handlers file for ansible-role-lutim
|
||||
|
||||
- name: restart nginx
|
||||
service: name=nginx state=restarted
|
||||
23
.provision/ansible-role-lutim/tasks/apprun.yaml
Normal file
23
.provision/ansible-role-lutim/tasks/apprun.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
#apprun.yml
|
||||
---
|
||||
- name: This command will install the postgress module
|
||||
ansible.builtin.shell:
|
||||
cmd: carton install --deployment --without=test --without=sqlite
|
||||
chdir: "{{ app_dir }}"
|
||||
|
||||
- name: Upload application config file
|
||||
ansible.builtin.template:
|
||||
src: ../templates/lutim.conf.j2
|
||||
dest: "{{ app_dir }}/lutim.conf"
|
||||
|
||||
- name: App executes
|
||||
ansible.builtin.shell:
|
||||
cmd: carton exec hypnotoad script/lutim
|
||||
chdir: "{{ app_dir }}"
|
||||
|
||||
- name: Nginx configuration file add
|
||||
ansible.builtin.template:
|
||||
src: ../templates/app.conf
|
||||
dest: /etc/nginx/conf.d/
|
||||
mode: '0644'
|
||||
notify: restart nginx
|
||||
21
.provision/ansible-role-lutim/tasks/cronjob.yaml
Normal file
21
.provision/ansible-role-lutim/tasks/cronjob.yaml
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
- name: Copy the cronjob file
|
||||
ansible.builtin.copy:
|
||||
src: ../files/cronjob
|
||||
dest: /etc/cron.d/lutim
|
||||
owner: www-data
|
||||
group: www-data
|
||||
|
||||
- name: "example cronjob"
|
||||
ansible.builtin.cron:
|
||||
name: "cronjob"
|
||||
state: present
|
||||
user: www-data
|
||||
minute: "0"
|
||||
hour: "0"
|
||||
day: "*"
|
||||
month: "*"
|
||||
weekday: "*"
|
||||
job: |
|
||||
carton exec script/lutim cron cleanbdd --mode production; carton exec script/lutim cron cleanfiles --mode production; carton exec script/lutim cron watch --mode production
|
||||
|
||||
23
.provision/ansible-role-lutim/tasks/dependencies.yaml
Normal file
23
.provision/ansible-role-lutim/tasks/dependencies.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
# dependencies.yaml
|
||||
---
|
||||
- name: Lutim | Update apt cache
|
||||
ansible.builtin.apt: update_cache=yes
|
||||
changed_when: no
|
||||
- name: Install Dependencies
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- nginx
|
||||
- carton
|
||||
- build-essential
|
||||
- libssl-dev
|
||||
- libpq-dev
|
||||
- libio-socket-ssl-perl
|
||||
- zlib1g-dev
|
||||
- libmojo-sqlite-perl
|
||||
- shared-mime-info
|
||||
- perlmagick
|
||||
state: present
|
||||
|
||||
|
||||
|
||||
|
||||
18
.provision/ansible-role-lutim/tasks/gitclone.yaml
Normal file
18
.provision/ansible-role-lutim/tasks/gitclone.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
#gitclone
|
||||
---
|
||||
|
||||
- name: clone the repository
|
||||
ansible.builtin.git:
|
||||
repo: 'https://framagit.org/fiat-tux/hat-softwares/lutim.git'
|
||||
dest: "{{ app_dir }}"
|
||||
clone: yes
|
||||
update: yes
|
||||
version: "{{ project_version }}"
|
||||
|
||||
- name: Change the owner
|
||||
ansible.builtin.file:
|
||||
path: "{{ app_dir }}"
|
||||
owner: "{{ lutim_owner }}"
|
||||
group: "{{ lutim_group }}"
|
||||
state: directory
|
||||
recurse: yes
|
||||
7
.provision/ansible-role-lutim/tasks/main.yml
Normal file
7
.provision/ansible-role-lutim/tasks/main.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
# tasks file for ansible-role-lutim
|
||||
|
||||
- include: dependencies.yaml
|
||||
- include: gitclone.yaml
|
||||
- include: apprun.yaml
|
||||
- include: cronjob.yaml
|
||||
43
.provision/ansible-role-lutim/templates/app.conf
Normal file
43
.provision/ansible-role-lutim/templates/app.conf
Normal file
@@ -0,0 +1,43 @@
|
||||
server {
|
||||
listen 80;
|
||||
# No need to have a `root` parameter.
|
||||
server_name {{ _server_name }};
|
||||
# This is important for user's privacy !
|
||||
access_log off;
|
||||
error_log /var/log/nginx/lutim.error.log;
|
||||
# This is important ! Make it OK with your Lutim configuration
|
||||
client_max_body_size 40M;
|
||||
|
||||
location ~* ^/(img|css|font|js)/ {
|
||||
try_files $uri @lutim;
|
||||
add_header Expires "Thu, 31 Dec 2037 23:55:55 GMT";
|
||||
add_header Cache-Control "public, max-age=315360000";
|
||||
|
||||
# HTTPS only header, improves security
|
||||
#add_header Strict-Transport-Security "max-age=15768000";
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri @lutim;
|
||||
|
||||
# HTTPS only header, improves security
|
||||
#add_header Strict-Transport-Security "max-age=15768000";
|
||||
}
|
||||
|
||||
location @lutim {
|
||||
# Adapt this to your configuration
|
||||
proxy_pass http://127.0.0.1:8080;
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
# If you want to log the remote port of the image senders, you'll need that
|
||||
proxy_set_header X-Remote-Port $remote_port;
|
||||
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# We expect the downsteam servers to redirect to the right hostname, so don't do any rewrites here.
|
||||
proxy_redirect off;
|
||||
}
|
||||
}
|
||||
317
.provision/ansible-role-lutim/templates/lutim.conf.j2
Normal file
317
.provision/ansible-role-lutim/templates/lutim.conf.j2
Normal file
@@ -0,0 +1,317 @@
|
||||
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
|
||||
{
|
||||
####################
|
||||
# Hypnotoad settings
|
||||
####################
|
||||
# see http://mojolicio.us/perldoc/Mojo/Server/Hypnotoad for a full list of settings
|
||||
hypnotoad => {
|
||||
# array of IP addresses and ports you want to listen to
|
||||
listen => ['http://127.0.0.1:8080'],
|
||||
# if you use Lutim behind a reverse proxy like Nginx, you want to set proxy to 1
|
||||
# if you use Lutim directly, let it commented
|
||||
#proxy => 1,
|
||||
},
|
||||
|
||||
################
|
||||
# Lutim settings
|
||||
################
|
||||
|
||||
# put a way to contact you here and uncomment it
|
||||
# mandatory
|
||||
contact => '{{ _contact }}',
|
||||
|
||||
# random string used to encrypt cookies
|
||||
# mandatory
|
||||
secrets => ['{{ _secrets }}'],
|
||||
|
||||
# choose a theme. See the available themes in `themes` directory
|
||||
# optional, default is 'default'
|
||||
#theme => 'default',
|
||||
|
||||
# length of the images random URL
|
||||
# optional, default is 8
|
||||
#length => 8,
|
||||
|
||||
# length of the encryption key
|
||||
# optional, default is 8
|
||||
#crypto_key_length => 8,
|
||||
|
||||
# how many URLs will be provisioned in a batch ?
|
||||
# optional, default is 5
|
||||
#provis_step => 5,
|
||||
|
||||
# max number of URLs to be provisioned
|
||||
# optional, default is 100
|
||||
#provisioning => 100,
|
||||
|
||||
# anti-flood protection delay, in seconds
|
||||
# users won't be able to ask Lutim to download images more than one per anti_flood_delay seconds
|
||||
# optional, default is 5
|
||||
#anti_flood_delay => 5,
|
||||
|
||||
# twitter account which will appear on twitter cards
|
||||
# see https://dev.twitter.com/docs/cards/validation/validator to register your Lutim instance on twitter
|
||||
# optional, no default
|
||||
#tweet_card_via => '@foo',
|
||||
|
||||
# max image size, in octets
|
||||
# you can write it 10*1024*1024
|
||||
# optional, default is 10485760
|
||||
#max_file_size => 10485760,
|
||||
|
||||
# if you want to have piwik statistics, provide a piwik image tracker
|
||||
# only the image tracker is allowed, no javascript
|
||||
# optional, no default
|
||||
#piwik_img => 'https://piwik.example.org/piwik.php?idsite=1&rec=1',
|
||||
|
||||
# if you want to include something in the right of the screen, put it here
|
||||
# here's an example to put the logo of your hoster
|
||||
# optional, no default
|
||||
#hosted_by => 'My super hoster <img src="http://hoster.example.com" alt="Hoster logo">',
|
||||
|
||||
# DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED
|
||||
# Lutim now checks if the X-Forwarded-Proto header is present and equal to https.
|
||||
# set to 1 if you use Lutim behind a secure web server
|
||||
# optional, default is 0
|
||||
#https => 0,
|
||||
|
||||
# broadcast_message which will displayed on all pages of Lutim (but no in json response)
|
||||
# optional, no default
|
||||
#broadcast_message => 'Maintenance',
|
||||
|
||||
# array of authorized domains for API calls.
|
||||
# if you want to authorize everyone to use the API: ['*']
|
||||
# optional, no domains allowed by default
|
||||
#allowed_domains => ['http://1.example.com', 'http://2.example.com'],
|
||||
|
||||
# default time limit for files
|
||||
# valid values are 0, 1, 7, 30 and 365
|
||||
# optional, default is 0 (no limit)
|
||||
#default_delay => 0,
|
||||
|
||||
# comma-separated values proposed for delays
|
||||
# optional, default is '0,1,7,30,365'
|
||||
#proposed_delays => '0,1,7,30,365',
|
||||
|
||||
# number of days after which the images will be deleted, even if they were uploaded with "no delay" (or value superior to max_delay)
|
||||
# a warning message will be displayed on homepage
|
||||
# optional, default is 0 (no limit)
|
||||
#max_delay => 0,
|
||||
|
||||
# if set to 1, all the images will be encrypted and the encryption option will no be displayed
|
||||
# optional, default is 0
|
||||
#always_encrypt => 0,
|
||||
|
||||
# you can allow to use a watermark on the uploaded images (or enforce its use)
|
||||
# define a path to the watermark image (provide an image with alpha channel)
|
||||
# you can define the path relative to lutim directory or set an absolute path
|
||||
# to disable the usage of a watermark, leave it blank or commented
|
||||
# optional, no default
|
||||
#watermark_path => '',
|
||||
|
||||
# the watermark can be a tiling one or a single one
|
||||
# when using a small one, you can choose where to place it
|
||||
# valid values are 'Center', 'North', 'NorthEast', 'East', 'SouthEast', 'South', 'SouthWest', 'West' and 'NorthWest' (case insensitive)
|
||||
# optional, default is 'SouthEast'
|
||||
#watermark_placement => 'SouthEast',
|
||||
|
||||
# choose which watermark (tiling, single or none) should be used by default
|
||||
# valid values are 'tiling', 'single' or 'none' (case insensitive)
|
||||
# optional, default is 'none'
|
||||
#watermark_default => 'none',
|
||||
|
||||
# choose which watermark (tiling, single or none) should be enforced (users will always have a watermark and won’t be able to disable it)
|
||||
# valid values are 'tiling', 'single' or 'none' (case insensitive)
|
||||
# optional, default is 'none'
|
||||
#watermark_enforce => 'none',
|
||||
|
||||
# length of the image's delete token
|
||||
# optional, default is 24
|
||||
#token_length => 24,
|
||||
|
||||
# URL sub-directory in which you want Lutim to be accessible
|
||||
# example: you want to have Lutim under https://example.org/lutim/
|
||||
# => set prefix to '/lutim' or to '/lutim/', it doesn't matter
|
||||
# optional, defaut is /
|
||||
#prefix => '/',
|
||||
|
||||
# choose what database you want to use
|
||||
# valid choices are sqlite and postgresql (all lowercase)
|
||||
# optional, default is sqlite
|
||||
#dbtype => 'sqlite',
|
||||
|
||||
# SQLite ONLY - only used if dbtype is set to sqlite
|
||||
# define a path to the SQLite database
|
||||
# you can define it relative to lutim directory or set an absolute path
|
||||
# remember that it has to be in a directory writable by Lutim user
|
||||
# optional, default is lutim.db
|
||||
#db_path => 'lutim.db',
|
||||
|
||||
# PostgreSQL ONLY - only used if dbtype is set to postgresql
|
||||
# these are the credentials to access the PostgreSQL database
|
||||
# mandatory if you choosed postgresql as dbtype
|
||||
pgdb => {
|
||||
database => 'lutim',
|
||||
host => 'localhost',
|
||||
user => 'DBUSER',
|
||||
pwd => 'DBPASSWORD'
|
||||
},
|
||||
|
||||
# use Minion instead of directly increase counters
|
||||
# need to launch a minion worker service if enabled
|
||||
# optional, Minion is disabled by default
|
||||
minion => {
|
||||
enabled => 0,
|
||||
# # Which Minion backend to use?
|
||||
# # valid values are sqlite and postgresql (all lowercase)
|
||||
# # mandatory if Minion is enabled, default is sqlite
|
||||
# dbtype => 'sqlite',
|
||||
# # SQLite ONLY - only used if if you choose sqlite as Minion backend, define the path to the minion database
|
||||
# # you can define it relative to lutim directory or set an absolute path
|
||||
# # remember that it has to be in a directory writable by Lutim user
|
||||
# # optional, default is minion.db
|
||||
db_path => 'minion.db',
|
||||
# # PostgreSQL ONLY - only used if you choose postgresql as Minion backend
|
||||
# # these are the credentials to access the Minion's PostgreSQL database
|
||||
# # mandatory if you choosed postgresql as Minion backend, no default
|
||||
pgdb => {
|
||||
database => 'lutim_minion',
|
||||
host => 'localhost',
|
||||
user => 'DBUSER',
|
||||
pwd => 'DBPASSWORD'
|
||||
}
|
||||
},
|
||||
|
||||
# set `ldap` if you want that only authenticated users can shorten URLs
|
||||
# please note that everybody can still use shortend URLs
|
||||
# optional, no default
|
||||
#ldap => {
|
||||
# uri => 'ldaps://ldap.example.org', # server URI
|
||||
# user_tree => 'ou=users,dc=example,dc=org', # search base DN
|
||||
# bind_dn => 'uid=ldap_user,ou=users,dc=example,dc=org', # search bind DN
|
||||
# bind_pwd => 'secr3t', # search bind password
|
||||
# user_attr => 'uid', # user attribute (uid, mail, sAMAccountName, etc.)
|
||||
# user_filter => '(!(uid=ldap_user))', # user filter (to exclude some users, etc.)
|
||||
#},
|
||||
|
||||
# set `htpasswd` if you want to use an htpasswd file instead of ldap
|
||||
# create the file with `htpasswd -c lutim.passwd user`, update it with `htpasswd lutim.passwd user2`
|
||||
# make sure that lutim can read the file!
|
||||
# optional, no default
|
||||
#htpasswd => 'lutim.passwd',
|
||||
|
||||
# if you've set ldap or htpasswd above, the session will last `session_duration` seconds before
|
||||
# the user needs to reauthenticate
|
||||
# optional, default is 3600
|
||||
#session_duration => 3600,
|
||||
|
||||
# disable counters of images
|
||||
# set to 1 to disable counters
|
||||
# optional, counters are enabled by default
|
||||
#disable_img_stats => 0,
|
||||
|
||||
# define the height of the thumbnails generated at users' will
|
||||
# this is not the height of the thumbnails send after upload,
|
||||
# we're talking about thumbnails generated when someone asked for
|
||||
# https://example.org/lutim/tesrinp?thumb
|
||||
# this works only if you have ImageMagick
|
||||
# optional, default is 100 (pixels)
|
||||
#thumbnail_size => 100,
|
||||
|
||||
# maximum number of files that can be downloaded as a single zip archive
|
||||
# if too many files are asked, it results a timeout, so Lutim split the zip URL
|
||||
# in multiple URLs, each with max_file_size images.
|
||||
# timeout behavior depends heavily on your server ressources (CPU) and if images
|
||||
# are encrypted
|
||||
# optional, default is 15
|
||||
#max_files_in_zip => 15,
|
||||
|
||||
# maximum size (in MB) of memory allowed for the image cache
|
||||
# Lutim has a built-in memory-based image cache to accelerate responses to often-viewed images.
|
||||
# This setting makes the cache remove oldest viewed image if the cache size is over it.
|
||||
# WARNING: a cache is created for each hypnotoad worker, which by default is twice the number of
|
||||
# CPUs you have. See http://mojolicious.org/perldoc/Mojo/Server/Hypnotoad#workers for details
|
||||
# So, if you have 4 workers and set cache_max_size to 100, the real maximum size of RAM used for
|
||||
# cache is 400MB.
|
||||
# If set to 0, the cache is disabled
|
||||
# optional, default is 0
|
||||
#cache_max_size => 0,
|
||||
|
||||
# array of memcached servers to cache URL in order to accelerate responses to often-viewed URL.
|
||||
# If set to [], the use of memcached is disabled.
|
||||
# If you use memcached, the internal cache (see cache_max_size option above) will not be used.
|
||||
# Please see https://framagit.org/luc/lutim/wikis/memcached to know how to configure your memcached
|
||||
# servers.
|
||||
# exemple of valid value: ['127.0.0.1:11211']
|
||||
# optional, default is []
|
||||
#memcached_servers => [],
|
||||
|
||||
# enable or disable Lutim built-in logs
|
||||
# set to 1 to disable logs
|
||||
# optional, default is 0
|
||||
#quiet_logs => 0,
|
||||
|
||||
# Content-Security-Policy header that will be sent by Lstu
|
||||
# Set to '' to disable CSP header
|
||||
# https://content-security-policy.com/ provides a good documentation about CSP.
|
||||
# https://report-uri.com/home/generate provides a tool to generate a CSP header.
|
||||
# optional, default is "base-uri 'self'; connect-src 'self'; default-src 'none'; font-src 'self'; form-action 'self'; img-src 'self' data:; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'"
|
||||
# NB: unsafe-inline for script-src and style-src are here only because morris,
|
||||
# the graph library used in the stats page requires it
|
||||
# the default value is good for `default` theme
|
||||
#csp => "base-uri 'self'; connect-src 'self'; default-src 'none'; font-src 'self'; form-action 'self'; img-src 'self' data:; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'",
|
||||
|
||||
# X-Frame-Options header that will be sent by Lstu
|
||||
# Valid values are: 'DENY', 'SAMEORIGIN', 'ALLOW-FROM https://example.com/'
|
||||
# Set to '' to disable X-Frame-Options header
|
||||
# See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
|
||||
# Please note that this will add a "frame-ancestors" directive to the CSP header (see above) accordingly
|
||||
# to the chosen setting (See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors)
|
||||
# optional, default is 'DENY'
|
||||
#x_frame_options => 'DENY',
|
||||
|
||||
# X-Content-Type-Options that will be sent by Lstu
|
||||
# See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
|
||||
# Set to '' to disable X-Content-Type-Options header
|
||||
# optional, default is 'nosniff'
|
||||
#x_content_type_options => 'nosniff',
|
||||
|
||||
# X-XSS-Protection that will be sent by Lstu
|
||||
# See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection
|
||||
# Set to '' to disable X-XSS-Protection header
|
||||
# optional, default is '1; mode=block'
|
||||
#x_xss_protection => '1; mode=block',
|
||||
|
||||
# if set, the uploaded images will use this domain
|
||||
# optional
|
||||
#fixed_domain => 'example.org',
|
||||
|
||||
##########################
|
||||
# Lutim cron jobs settings
|
||||
##########################
|
||||
|
||||
# number of days shown in /stats page (used with script/lutim cron stats)
|
||||
# optional, default is 365
|
||||
stats_day_num => 365,
|
||||
|
||||
# number of days senders' IP addresses are kept in database
|
||||
# after that delay, they will be deleted from database (used with script/lutim cron cleanbdd)
|
||||
# optional, default is 365
|
||||
keep_ip_during => 365,
|
||||
|
||||
# max size of the files directory, in octets
|
||||
# used by script/lutim cron watch to trigger an action
|
||||
# optional, no default
|
||||
max_total_size => 10*1024*1024*1024,
|
||||
|
||||
# default action when files directory is over max_total_size (used with script/lutim cron watch)
|
||||
# valid values are 'warn', 'stop-upload' and 'delete'
|
||||
# please, see readme
|
||||
# optional, default is 'warn'
|
||||
#policy_when_full => 'warn',
|
||||
|
||||
# images which are not viewed since delete_no_longer_viewed_files days will be deleted by the cron cleanfiles task
|
||||
# if delete_no_longer_viewed_files is not set, the no longer viewed files will NOT be deleted
|
||||
# optional, no default
|
||||
delete_no_longer_viewed_files => 90
|
||||
};
|
||||
16
.provision/ansible-role-lutim/vars/main.yml
Normal file
16
.provision/ansible-role-lutim/vars/main.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
# vars file for ansible-role-lutim
|
||||
|
||||
lutim_owner: "www-data"
|
||||
|
||||
lutim_group: "www-data"
|
||||
|
||||
app_dir: "/var/www/lutim"
|
||||
|
||||
_contact: ""
|
||||
|
||||
_secrets: ""
|
||||
|
||||
_project_version: ""
|
||||
|
||||
_servername: ""
|
||||
92
.provision/terraform-aws-lutim/README.md
Normal file
92
.provision/terraform-aws-lutim/README.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# Terraform-AWS-Deploy
|
||||
|
||||
This terraform plan create the resourcess of EC2 instance
|
||||
|
||||
## Terraform Variables
|
||||
Edit the `vars.tf` file to add the variables as per your need.
|
||||
|
||||
| Variable name | Value | Description |
|
||||
| ------------- | ----- | ----------- |
|
||||
| `aws_region` | us-east-1 | Set the region |
|
||||
| `vpc_cidr` | 10.0.0.0/16 | Set the cidr value for the vpc |
|
||||
| `public_subnet_cidr` | 10.0.2.0/24 | Set the cidr value for the public subnet |
|
||||
| `user` | ubuntu | Set the EC2 instance user name |
|
||||
| `public_key` | /home/user_name/.ssh/id_rsa_pub | Set the publickey value for the ec2 instance from the host machine |
|
||||
| `private_key` | /home/user_name/.ssh/id_rsa | Set the private key value for the ec2 instance from the hostmachine |
|
||||
| `aws_access_key` | AWSACCESSKEY | Enter your aws access key |
|
||||
| `aws_secrete_key` | AWSSECRETEKEY | Enter your aws secrete key |
|
||||
| `instance_name` | lutim_app_instance | Set the name for instance |
|
||||
| `app_dir` | /var/www/lutim | Set the application directory for the best practice |
|
||||
| `lutim_owner` | www-data | Set the application user for the best practice |
|
||||
| `lutim_group` | www-data | Set the application group for the best practice |
|
||||
| `contact` | contact.example.com | Contact option (mandatory), where you have to put some way for the users to contact you. |
|
||||
| `contact_user` | name | Name of the user |
|
||||
| `secrets` | ffyg7kbkjba | Secrets option (mandotory), which is array of random string. Used by Mojolicious for encrypting session cookies |
|
||||
| `app_dir` | /var/www/lutim | Set the application directory for the best practice |
|
||||
| `lutim_owner` | www-data | Set the application user for the best practice |
|
||||
| `lutim_group` | www-data | Set the application group for the best practice |
|
||||
| `contact` | contact.example.com | Contact option (mandatory), where you have to put some way for the users to contact you. |
|
||||
| `contact_user` | name | Name of the user |
|
||||
| `secrets` | ffyg7kbkjba | Secrets option (mandotory), which is array of random string. Used by Mojolicious for encrypting session cookies |
|
||||
|
||||
## Usage of terraform plan with lufi deploy script
|
||||
|
||||
```sh
|
||||
git clone https://framagit.org/fiat-tux/hat-softwares/lutim.git
|
||||
|
||||
cd lutim/.provision/terraform-aws-lutim
|
||||
|
||||
terraform init
|
||||
terraform plan
|
||||
terraform apply
|
||||
```
|
||||
## Usage of terraform plan with ansible role
|
||||
|
||||
- Comment out the below `locals` and `user_data` source in __main.tf__ file
|
||||
|
||||
```hcl
|
||||
locals {
|
||||
user_data_vars = {
|
||||
user = var.lutim_owner
|
||||
group = var.lutim_group
|
||||
directory = var.app_dir
|
||||
contact_user = var.contact_user
|
||||
contact_lutim = var.contact
|
||||
secret_lutim = var.secret
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```hcl
|
||||
user_data = templatefile("${path.module}/lutim_startup.sh", local.user_data_vars)
|
||||
```
|
||||
|
||||
- Add the below provisioner data in __main.tf__ file at the `aws_instance` resource
|
||||
|
||||
```sh
|
||||
connection {
|
||||
agent = false
|
||||
type = "ssh"
|
||||
host = aws_instance.ec2_instance.public_dns
|
||||
private_key = "${file(var.private_key)}"
|
||||
user = "${var.user}"
|
||||
}
|
||||
|
||||
provisioner "remote-exec" {
|
||||
inline = [
|
||||
"sudo apt update -y",
|
||||
"sudo apt install python3.9 -y",
|
||||
]
|
||||
}
|
||||
|
||||
provisioner "local-exec" {
|
||||
command = <<EOT
|
||||
sleep 120 && \
|
||||
> hosts && \
|
||||
echo "[Lutim]" | tee -a hosts && \
|
||||
echo "${aws_instance.ec2_instance.public_ip} ansible_user=${var.user} ansible_ssh_private_key_file=${var.private_key}" | tee -a hosts && \
|
||||
export ANSIBLE_HOST_KEY_CHECKING=False && \
|
||||
ansible-playbook -u ${var.user} --private-key ${var.private_key} -i hosts site.yml
|
||||
EOT
|
||||
}
|
||||
```
|
||||
66
.provision/terraform-aws-lutim/lutim_startup.sh
Normal file
66
.provision/terraform-aws-lutim/lutim_startup.sh
Normal file
@@ -0,0 +1,66 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "**********************************************************************"
|
||||
echo " *"
|
||||
echo "Install dependencies *"
|
||||
echo " *"
|
||||
echo "**********************************************************************"
|
||||
|
||||
SUDO=sudo
|
||||
$SUDO apt update
|
||||
$SUDO apt install jq -y
|
||||
$SUDO apt install wget -y
|
||||
$SUDO apt install unzip
|
||||
$SUDO apt install carton -y
|
||||
$SUDO apt install build-essential -y
|
||||
$SUDO apt install nginx -y
|
||||
$SUDO apt install libssl-dev -y
|
||||
$SUDO apt install libio-socket-ssl-perl -y
|
||||
$SUDO apt install liblwp-protocol-https-perl -y
|
||||
$SUDO apt install zlib1g-dev -y
|
||||
$SUDO apt install libmojo-sqlite-perl -y
|
||||
$SUDO apt install libpq-dev -y
|
||||
|
||||
echo "**********************************************************************"
|
||||
echo " *"
|
||||
echo "Configuring the Application *"
|
||||
echo " *"
|
||||
echo "**********************************************************************"
|
||||
|
||||
sleep 10;
|
||||
version=$(curl -s https://framagit.org/api/v4/projects/1/releases | jq '.[]' | jq -r '.name' | head -1)
|
||||
echo $version
|
||||
pushd ${directory}
|
||||
$SUDO wget https://framagit.org/fiat-tux/hat-softwares/lutim/-/archive/$version/lutim-$version.zip
|
||||
$SUDO unzip lutim-$version.zip
|
||||
$SUDO chown ${user} lutim-$version
|
||||
$SUDO chgrp ${group} lutim-$version
|
||||
pushd lutim-$version
|
||||
|
||||
echo "**********************************************************************"
|
||||
echo " *"
|
||||
echo "Install Carton Packages *"
|
||||
echo " *"
|
||||
echo "**********************************************************************"
|
||||
|
||||
$SUDO carton install --deployment --without=test --without=sqlite --without=mysql
|
||||
|
||||
sleep 10;
|
||||
|
||||
$SUDO cp lutim.conf.template lutim.conf
|
||||
|
||||
sed -i 's/127.0.0.1/0.0.0.0/' lutim.conf
|
||||
sed -i 's/#contact/contact/g' lutim.conf
|
||||
sed -i "s/John Doe/${contact_user}/g" lutim.conf
|
||||
sed -i "s/admin[at]example.com/${contact_lutim}/g" lutim.conf
|
||||
sed -i "s/fdjsofjoihrei/${secret_lutim}/g" lutim.conf
|
||||
sed -i '153 , 158 s/#/ /g' lutim.conf
|
||||
|
||||
echo "**********************************************************************"
|
||||
echo " *"
|
||||
echo "Run the Application *"
|
||||
echo " *"
|
||||
echo "**********************************************************************"
|
||||
|
||||
$SUDO carton exec hypnotoad script/lutim
|
||||
|
||||
123
.provision/terraform-aws-lutim/main.tf
Normal file
123
.provision/terraform-aws-lutim/main.tf
Normal file
@@ -0,0 +1,123 @@
|
||||
locals {
|
||||
user_data_vars = {
|
||||
user = var.lutim_owner
|
||||
group = var.lutim_group
|
||||
directory = var.app_dir
|
||||
contact_user = var.contact_user
|
||||
contact_lutim = var.contact
|
||||
secret_lutim = var.secret
|
||||
}
|
||||
}
|
||||
|
||||
#Create the VPC
|
||||
resource "aws_vpc" "vpc" {
|
||||
cidr_block = "${var.vpc_cidr}"
|
||||
enable_dns_hostnames = true
|
||||
enable_dns_support = true
|
||||
instance_tenancy = "default"
|
||||
tags = {
|
||||
Name = "lutim-master-vpc"
|
||||
}
|
||||
}
|
||||
|
||||
# Create InternetGateWay and attach to VPC
|
||||
|
||||
resource "aws_internet_gateway" "IGW" {
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
tags = {
|
||||
"Name" = "lutim-master-igw"
|
||||
}
|
||||
}
|
||||
|
||||
# Create a public subnet
|
||||
|
||||
resource "aws_subnet" "publicsubnet" {
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
cidr_block = "${var.public_subnet_cidr}"
|
||||
map_public_ip_on_launch = true
|
||||
tags = {
|
||||
Name = "lutim-master-us-east-1-public"
|
||||
}
|
||||
}
|
||||
|
||||
# Create routeTable
|
||||
resource "aws_route_table" "publicroute" {
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
route {
|
||||
cidr_block = "0.0.0.0/0"
|
||||
gateway_id = "${aws_internet_gateway.IGW.id}"
|
||||
}
|
||||
|
||||
tags = {
|
||||
Name = "lutim-master-us-east-1-public-rt"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_main_route_table_association" "mainRTB" {
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
route_table_id = "${aws_route_table.publicroute.id}"
|
||||
}
|
||||
## Create security group
|
||||
resource "aws_security_group" "security" {
|
||||
name = "lutim-master-sg"
|
||||
description = "allow all traffic"
|
||||
vpc_id = "${aws_vpc.vpc.id}"
|
||||
|
||||
ingress {
|
||||
description = "allow all traffic"
|
||||
from_port = "0"
|
||||
to_port = "65535"
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
ingress {
|
||||
description = "allow port SSH"
|
||||
from_port = "22"
|
||||
to_port = "22"
|
||||
protocol = "tcp"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
egress {
|
||||
from_port = 0
|
||||
to_port = 0
|
||||
protocol = "-1"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Add ubuntu AMI
|
||||
data "aws_ami" "ubuntu" {
|
||||
most_recent = true
|
||||
owners = ["099720109477"]
|
||||
|
||||
filter {
|
||||
name = "name"
|
||||
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
|
||||
}
|
||||
}
|
||||
|
||||
#Create key_pair for the instance
|
||||
|
||||
resource "aws_key_pair" "genkey" {
|
||||
key_name = "lutim.webapp"
|
||||
public_key = "${file(var.public_key)}"
|
||||
}
|
||||
|
||||
# Craete ec2 instance
|
||||
resource "aws_instance" "ec2_instance" {
|
||||
ami = "${data.aws_ami.ubuntu.id}"
|
||||
instance_type = "t2.medium"
|
||||
associate_public_ip_address = "true"
|
||||
subnet_id = "${aws_subnet.publicsubnet.id}"
|
||||
vpc_security_group_ids = ["${aws_security_group.security.id}"]
|
||||
user_data = templatefile("${path.module}/lutim_startup.sh", local.user_data_vars)
|
||||
key_name = "lutim.webapp"
|
||||
|
||||
tags = {
|
||||
Name = "${var.instance_name}"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
7
.provision/terraform-aws-lutim/output.tf
Normal file
7
.provision/terraform-aws-lutim/output.tf
Normal file
@@ -0,0 +1,7 @@
|
||||
output "public_ip" {
|
||||
value = "${aws_instance.ec2_instance.public_ip}"
|
||||
}
|
||||
|
||||
output "App_running_at" {
|
||||
value = "http://${aws_instance.ec2_instance.public_ip}:8080"
|
||||
}
|
||||
14
.provision/terraform-aws-lutim/provider.tf
Normal file
14
.provision/terraform-aws-lutim/provider.tf
Normal file
@@ -0,0 +1,14 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = "~> 3.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "aws" {
|
||||
access_key = "${var.aws_access_key}"
|
||||
secret_key = "${var.aws_secret_key}"
|
||||
region = "${var.aws_region}"
|
||||
}
|
||||
60
.provision/terraform-aws-lutim/vars.tf
Normal file
60
.provision/terraform-aws-lutim/vars.tf
Normal file
@@ -0,0 +1,60 @@
|
||||
variable "aws_region" {
|
||||
default = "aws_region"
|
||||
}
|
||||
variable "vpc_cidr" {
|
||||
default = "cidr_value"
|
||||
}
|
||||
variable "public_subnet_cidr" {
|
||||
default = "cidr_value"
|
||||
}
|
||||
variable "public_subnet1_cidr" {
|
||||
default = "cidr_value"
|
||||
}
|
||||
|
||||
variable "user" {
|
||||
default = "user_of_instance"
|
||||
}
|
||||
|
||||
variable "public_key" {
|
||||
default = "$PWD_publickey"
|
||||
}
|
||||
variable "private_key" {
|
||||
default = "$PWD_privatekey"
|
||||
}
|
||||
variable "aws_access_key" {
|
||||
default = "aws_access_key"
|
||||
}
|
||||
|
||||
variable "aws_secret_key" {
|
||||
default = "aws_secrete_key"
|
||||
}
|
||||
|
||||
variable "instance_name" {
|
||||
default = "instance_name"
|
||||
}
|
||||
|
||||
variable "lutim_owner" {
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "lutim_group" {
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "app_dir" {
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "contact_user" {
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "contact" {
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "secret" {
|
||||
default = ""
|
||||
}
|
||||
|
||||
|
||||
16
CHANGELOG
16
CHANGELOG
@@ -1,6 +1,20 @@
|
||||
Revision history for Lutim
|
||||
|
||||
0.13.0 ????-??-??
|
||||
0.16.0 ????-??-??
|
||||
|
||||
0.15.0 2023-12-19
|
||||
- ✨ — Add --nuke option to image command
|
||||
|
||||
0.14.0 2023-12-18
|
||||
- ⬆️ Update dependencies
|
||||
- 💥 BREAKING CHANGE: Use `?_format=json` instead of `?format=json`
|
||||
- 💥 BREAKING CHANGE: Use `?_format=json` instead of terminating the URL with `.json`
|
||||
|
||||
0.13.0 2023-04-26
|
||||
- 💄 — Add Korrigan theme (Nicolas Frandeboeuf)
|
||||
- 🔥 — Remove zanata stuff
|
||||
- ✨ — Add a config flag to disable API (@b_b)
|
||||
- 🌐 — Update translations
|
||||
|
||||
0.12.1 2020-10-08
|
||||
- ⬆️ Update jQuery
|
||||
|
||||
35
Dockerfile
35
Dockerfile
@@ -1,10 +1,10 @@
|
||||
FROM alpine:3.9
|
||||
FROM alpine:3.15
|
||||
|
||||
ARG BUILD_DATE
|
||||
ARG VCS_REF
|
||||
ARG VERSION
|
||||
LABEL org.label-schema.build-date=$BUILD_DATE \
|
||||
org.label-schema.name="Let's Upload That Image" \
|
||||
org.label-schema.name="Lets Upload That Image" \
|
||||
org.label-schema.url="https://lut.im/" \
|
||||
org.label-schema.vcs-ref=$VCS_REF \
|
||||
org.label-schema.vcs-url="https://git.framasoft.org/luc/lutim" \
|
||||
@@ -12,12 +12,37 @@ LABEL org.label-schema.build-date=$BUILD_DATE \
|
||||
org.label-schema.version=$VERSION \
|
||||
org.label-schema.schema-version="1.0"
|
||||
|
||||
RUN adduser -D lutim
|
||||
COPY --chown=lutim:lutim . /home/lutim
|
||||
RUN adduser -D lutim \
|
||||
&& addgroup lutim root
|
||||
|
||||
COPY . /home/lutim
|
||||
RUN chmod -R g+rwX /home/lutim
|
||||
|
||||
WORKDIR /home/lutim
|
||||
RUN /bin/sh /home/lutim/docker/build.sh
|
||||
RUN apk --no-cache add perl~=5 \
|
||||
libpq~=14 \
|
||||
perl-crypt-rijndael~=1 \
|
||||
perl-io-socket-ssl~=2 \
|
||||
perl-net-ssleay~=1 \
|
||||
su-exec~=0.2 \
|
||||
shared-mime-info~=2 \
|
||||
libretls~=3 \
|
||||
imagemagick~=7 \
|
||||
imagemagick-perlmagick~=7 \
|
||||
bash~=~5 \
|
||||
&& apk --no-cache add --virtual .build-deps build-base~=0.5 \
|
||||
perl-utils~=5 \
|
||||
perl-dev~=5 \
|
||||
postgresql14-dev~=14 \
|
||||
vim~=8 \
|
||||
wget~=1 \
|
||||
zlib-dev~=1 \
|
||||
&& cpan notest Carton Config::FromHash \
|
||||
&& carton install --without test \
|
||||
&& apk del .build-deps \
|
||||
&& rm -rf /var/cache/apk/* /root/.cpan*
|
||||
|
||||
USER lutim
|
||||
EXPOSE 8080
|
||||
|
||||
ENTRYPOINT ["/bin/sh", "/home/lutim/docker/entrypoint.sh"]
|
||||
3
Makefile
3
Makefile
@@ -19,9 +19,6 @@ locales:
|
||||
$(XGETTEXT) $(EXTRACTDIR) -o $(POT) 2>/dev/null
|
||||
$(XGETTEXT) $(EXTRACTDIR) -o $(ENPO) 2>/dev/null
|
||||
|
||||
stats-locales:
|
||||
wlc stats
|
||||
|
||||
podcheck:
|
||||
podchecker lib/Lutim/DB/Image.pm
|
||||
|
||||
|
||||
@@ -68,3 +68,7 @@ It uses:
|
||||
* [JSZip](https://stuk.github.io/jszip/) for generating a zip containing all the images in the gallery
|
||||
* [FileSaver.js](https://github.com/eligrey/FileSaver.js/) for saving the zip
|
||||
* [Toastify JS](https://apvarun.github.io/toastify-js/) for notifications
|
||||
|
||||
## Deploy lutim
|
||||
|
||||
An ansible role and a terraform plan reside under the `.provision` directory. An user could utilize the terraform plan if they chose to deploy lutim on AWS, if that's not the goal, they could simply execute the ansible role in part. Usage docs for both are present in their respective directories.
|
||||
|
||||
1
cpanfile
1
cpanfile
@@ -15,6 +15,7 @@ requires 'Filesys::DiskUsage';
|
||||
requires 'Switch';
|
||||
requires 'Crypt::CBC';
|
||||
requires 'Crypt::Blowfish';
|
||||
requires 'Digest::MD5';
|
||||
requires 'Locale::Maketext';
|
||||
requires 'Locale::Maketext::Extract';
|
||||
requires 'File::MimeInfo';
|
||||
|
||||
3906
cpanfile.snapshot
3906
cpanfile.snapshot
File diff suppressed because it is too large
Load Diff
@@ -1,16 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
set -eu
|
||||
|
||||
apk update
|
||||
apk add perl libpq perl-crypt-rijndael perl-io-socket-ssl perl-net-ssleay su-exec shared-mime-info libressl
|
||||
sh $(dirname $0)/install-dev-env.sh
|
||||
|
||||
sh $(dirname $0)/install-imagemagick.sh
|
||||
|
||||
cpan notest Carton Config::FromHash
|
||||
carton install --without test
|
||||
|
||||
# Remove dev env
|
||||
apk del .build-deps
|
||||
rm -rf /var/cache/apk/* /root/.cpan*
|
||||
6
docker/entrypoint.sh
Normal file → Executable file
6
docker/entrypoint.sh
Normal file → Executable file
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
@@ -14,7 +14,7 @@ then
|
||||
echo ""
|
||||
echo "You can then install the build dependencies with this command"
|
||||
echo " sh ~lutim/docker/install-dev-env.sh"
|
||||
|
||||
|
||||
tail -f /dev/null
|
||||
exit 0
|
||||
fi
|
||||
@@ -28,7 +28,7 @@ then
|
||||
DB_HOST=$(perl utilities/read_conf.pl pgdb/host db)
|
||||
DB_PORT=$(perl utilities/read_conf.pl pgdb/port 5432)
|
||||
fi
|
||||
if [ -n "$DB_HOST" -a -n "$DB_PORT" ]
|
||||
if [ -n "$DB_HOST" ] && [ -n "$DB_PORT" ]
|
||||
then
|
||||
while ! nc -vz "${DB_HOST}" "${DB_PORT}"; do
|
||||
echo "Waiting for database..."
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
apk --update add --virtual .build-deps build-base perl-utils perl-dev postgresql-dev vim wget zlib-dev
|
||||
@@ -1,40 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Instructions from https://imagemagick.org/script/perl-magick.php
|
||||
|
||||
set -eu
|
||||
|
||||
IM_VERSION=7.0.8-41
|
||||
SHA256_DIGEST=93f73a245c25194f757c075df9f2ec40010376200cc664c21646565b8690112c
|
||||
|
||||
IM_DIR="ImageMagick-$IM_VERSION"
|
||||
TARBALL="$IM_DIR.tar.gz"
|
||||
|
||||
ORIG_DIR="$(pwd)"
|
||||
|
||||
apk add libgomp libgcc libmagic \
|
||||
libjpeg libjpeg-turbo-dev \
|
||||
libpng libpng-dev \
|
||||
tiff tiff-dev \
|
||||
libwebp libwebp-dev
|
||||
|
||||
mkdir -p /tmp/im-build
|
||||
cd /tmp/im-build
|
||||
|
||||
echo "$SHA256_DIGEST *$TARBALL" > SHA256SUM
|
||||
|
||||
wget https://imagemagick.org/download/$TARBALL -O $TARBALL
|
||||
sha256sum -c SHA256SUM
|
||||
|
||||
tar xvf $TARBALL
|
||||
cd $IM_DIR
|
||||
./configure --with-perl --with-jpeg --with-png --with-tiff --with-webp
|
||||
make -j$(nproc)
|
||||
make install
|
||||
|
||||
ldconfig /usr/local/lib
|
||||
perl -MImage::Magick -le 'print Image::Magick->QuantumDepth'
|
||||
|
||||
cd "$ORIG_DIR"
|
||||
apk del libjpeg-turbo-dev libpng-dev tiff-dev libwebp-dev
|
||||
rm -rf /tmp/im-build
|
||||
14
lib/Lutim.pm
14
lib/Lutim.pm
@@ -291,7 +291,7 @@ sub startup {
|
||||
});
|
||||
|
||||
$r->get('/')->
|
||||
over('authorized')->
|
||||
requires('authorized')->
|
||||
to('Image#home')->
|
||||
name('index');
|
||||
$r->get('/')->
|
||||
@@ -330,7 +330,7 @@ sub startup {
|
||||
to('Image#change_lang')->
|
||||
name('lang');
|
||||
|
||||
$r->get('/partial/:file' => sub {
|
||||
$r->get('/partial/<:file>.<:f>' => sub {
|
||||
my $c = shift;
|
||||
$c->render(
|
||||
template => 'partial/'.$c->param('file'),
|
||||
@@ -351,7 +351,7 @@ sub startup {
|
||||
})->name('gallery');
|
||||
|
||||
$r->get('/myfiles')->
|
||||
over('authorized')->
|
||||
requires('authorized')->
|
||||
name('myfiles');
|
||||
$r->get('/myfiles')->
|
||||
to('Authent#index');
|
||||
@@ -369,28 +369,28 @@ sub startup {
|
||||
->name('random');
|
||||
|
||||
$r->post('/')->
|
||||
over('authorized')->
|
||||
requires('authorized')->
|
||||
to('Image#add')->
|
||||
name('add');
|
||||
$r->post('/')->
|
||||
to('Authent#index');
|
||||
|
||||
$r->get('/d/:short/:token')->
|
||||
over('authorized')->
|
||||
requires('authorized')->
|
||||
to('Image#delete')->
|
||||
name('delete');
|
||||
$r->get('/d/:short/:token')->
|
||||
to('Authent#index');
|
||||
|
||||
$r->post('/m/:short/:token')->
|
||||
over('authorized')->
|
||||
requires('authorized')->
|
||||
to('Image#modify')->
|
||||
name('modify');
|
||||
$r->post('/m/:short/:token')->
|
||||
to('Authent#index');
|
||||
|
||||
$r->post('/c')->
|
||||
over('authorized')->
|
||||
requires('authorized')->
|
||||
to('Image#get_counter')->
|
||||
name('counter');
|
||||
$r->post('/c')->
|
||||
|
||||
@@ -46,7 +46,8 @@ sub run {
|
||||
'r|remove=s{1,}' => \my @remove,
|
||||
'y|yes' => \my $yes,
|
||||
'q|quiet' => \my $quiet,
|
||||
's|search=s' => \my $ip
|
||||
's|search=s' => \my $ip,
|
||||
'n|nuke=s' => \my $nuke,
|
||||
;
|
||||
|
||||
if (scalar @info) {
|
||||
@@ -85,9 +86,43 @@ sub run {
|
||||
push @shorts, $e->short;
|
||||
print_infos($e, $csv);
|
||||
});
|
||||
say sprintf('%d matching URLs', $u->size);
|
||||
say sprintf('%d matching images', $u->size);
|
||||
say sprintf("If you want to delete those images, please do:\n carton exec script/lutim image --remove %s", join(' ', @shorts)) if @shorts;
|
||||
}
|
||||
if ($nuke) {
|
||||
my $i = get_short($c, $nuke);
|
||||
if ($i && $i->created_by) {
|
||||
my $u = Lutim::DB::Image->new(app => $c->app)->search_exact_created_by($i->created_by);
|
||||
my @shorts;
|
||||
say sprintf('%d images created by the same IP address (%s) than image %s', $u->size, $i->created_by, $nuke);
|
||||
my $confirm = ($yes) ? 'yes' : undef;
|
||||
unless (defined $confirm) {
|
||||
printf('Are you sure you want to remove those %d images? [N/y] ', $u->size);
|
||||
$confirm = <STDIN>;
|
||||
chomp $confirm;
|
||||
}
|
||||
if ($confirm =~ m/^y(es)?$/i) {
|
||||
$u->each(sub {
|
||||
my ($e, $num) = @_;
|
||||
my $i = get_short($c, $e->short);
|
||||
if ($i) {
|
||||
print_infos($i, $csv);
|
||||
if ($i->enabled) {
|
||||
delete_short($c, $i, 1);
|
||||
} else {
|
||||
say sprintf('The image %s is already disabled', $e->short);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
say 'Answer was not "y" or "yes". Aborting deletion.';
|
||||
}
|
||||
} elsif (! $i->created_by) {
|
||||
say sprintf('Image %s does not contain its creator’s IP address.', $nuke);
|
||||
} else {
|
||||
say sprintf('Sorry, can’t find image %s', $nuke);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub get_short {
|
||||
@@ -168,7 +203,7 @@ sub delete_short {
|
||||
|
||||
my $confirm = ($y) ? 'yes' : undef;
|
||||
unless (defined $confirm) {
|
||||
printf('Are you sure you want to remove this image (%s) ? [N/y] ', $i->short);
|
||||
printf('Are you sure you want to remove this image (%s)? [N/y] ', $i->short);
|
||||
$confirm = <STDIN>;
|
||||
chomp $confirm;
|
||||
}
|
||||
@@ -191,6 +226,7 @@ Lutim::Command::image - Manage URL in Lutim's database
|
||||
carton exec script/lutim image --info <short> <short> [--csv] Print infos about the space-separated images (--csv creates a CSV output)
|
||||
carton exec script/lutim image --remove <short> <short> [--yes] [--quiet] Delete the space-separated images (--yes disables confirmation, --quiet disables informations printing)
|
||||
carton exec script/lutim image --search <ip> Print infos about the images uploaded by this IP (database LIKE, may include images uploaded by other IPs)
|
||||
carton exec script/lutim image --nuke <short> Delete the image and all images sent by the same IP address and print infos about the deleted images
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# vim:set sw=4 ts=4 sts=4 expandtab:
|
||||
package Lutim::Controller::Image;
|
||||
use Mojo::Asset::Memory;
|
||||
use Mojo::Base 'Mojolicious::Controller';
|
||||
use Mojo::Util qw(url_escape url_unescape b64_encode encode);
|
||||
use Mojo::Asset::Memory;
|
||||
use Mojo::JSON qw(true false);
|
||||
use Lutim::DB::Image;
|
||||
use DateTime;
|
||||
@@ -287,6 +287,22 @@ sub add {
|
||||
my $keep_exif = $c->param('keep-exif');
|
||||
my $wm = $c->param('watermark');
|
||||
|
||||
if ($c->config('disable_api')) {
|
||||
my $unauthorized_api = (!defined($c->req->headers->referrer) || Mojo::URL->new($c->req->headers->referrer)->host ne Mojo::URL->new('https://'.$c->req->headers->host)->host);
|
||||
if ($unauthorized_api) {
|
||||
my $msg = $c->l('Sorry, the API is disabled');
|
||||
$c->app->log->info('Blocked API call for '.$c->ip(1));
|
||||
return $c->respond_to(
|
||||
json => { json => { success => Mojo::JSON->false, msg => $msg } },
|
||||
any => sub {
|
||||
shift->render(
|
||||
template => 'index',
|
||||
msg => $msg,
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
if(!defined($c->stash('stop_upload'))) {
|
||||
if (defined($file_url) && $file_url) {
|
||||
if (is_http_uri($file_url) || is_https_uri($file_url)) {
|
||||
@@ -471,12 +487,10 @@ sub add {
|
||||
if ($mediatype ne 'image/svg+xml' && $mediatype !~ m#image/(x-)?xcf# && $mediatype ne 'image/webp') {
|
||||
# Remove the EXIF tags
|
||||
my $data = new IO::Scalar \$upload->slurp();
|
||||
my $et = new Image::ExifTool;
|
||||
my $et = Image::ExifTool->new;
|
||||
|
||||
# Use $data in Image::ExifTool object
|
||||
$et->ExtractInfo($data);
|
||||
# Remove all metadata
|
||||
$et->SetNewValue('*', undef);
|
||||
$et->SetNewValue('*');
|
||||
|
||||
# Create a temporary IO::Scalar to write into
|
||||
my $temp;
|
||||
|
||||
@@ -345,6 +345,20 @@ sub to_hash {
|
||||
|
||||
=back
|
||||
|
||||
=head2 search_exact_created_by
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<Usage> : C<$c-E<gt>search_exact_created_by($ip)>
|
||||
|
||||
=item B<Arguments> : an IP address
|
||||
|
||||
=item B<Purpose> : get enabled images that have been uploaded by this IP address
|
||||
|
||||
=item B<Returns> : a Mojo::Collection object containing the matching images as Lutim::DB::Image objects
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
|
||||
@@ -213,6 +213,27 @@ sub search_created_by {
|
||||
return c(@images);
|
||||
}
|
||||
|
||||
sub search_exact_created_by {
|
||||
my $c = shift;
|
||||
my $ip = shift;
|
||||
|
||||
my @images;
|
||||
|
||||
my $records = $c->app->pg->db->select('lutim', undef, { enabled => 1, created_by => $ip })->hashes;
|
||||
|
||||
$records->each(
|
||||
sub {
|
||||
my ($e, $num) = @_;
|
||||
my $i = Lutim::DB::Image->new(app => $c->app);
|
||||
$i->_slurp($e);
|
||||
|
||||
push @images, $i;
|
||||
}
|
||||
);
|
||||
|
||||
return c(@images);
|
||||
}
|
||||
|
||||
sub _slurp {
|
||||
my $c = shift;
|
||||
my $r = shift;
|
||||
|
||||
@@ -214,6 +214,27 @@ sub search_created_by {
|
||||
return c(@images);
|
||||
}
|
||||
|
||||
sub search_exact_created_by {
|
||||
my $c = shift;
|
||||
my $ip = shift;
|
||||
|
||||
my @images;
|
||||
|
||||
my $records = $c->app->sqlite->db->select('lutim', undef, { enabled => 1, created_by => $ip })->hashes;
|
||||
|
||||
$records->each(
|
||||
sub {
|
||||
my ($e, $num) = @_;
|
||||
my $i = Lutim::DB::Image->new(app => $c->app);
|
||||
$i->_slurp($e);
|
||||
|
||||
push @images, $i;
|
||||
}
|
||||
);
|
||||
|
||||
return c(@images);
|
||||
}
|
||||
|
||||
sub _slurp {
|
||||
my $c = shift;
|
||||
my $r = shift;
|
||||
|
||||
@@ -22,6 +22,7 @@ our $default_config = {
|
||||
watermark_default => 'none',
|
||||
watermark_enforce => 'none',
|
||||
theme => 'default',
|
||||
disable_api => 0,
|
||||
dbtype => 'sqlite',
|
||||
db_path => 'lutim.db',
|
||||
max_files_in_zip => 15,
|
||||
|
||||
@@ -8,6 +8,7 @@ use Data::Entropy qw(entropy_source);
|
||||
use DateTime;
|
||||
use Mojo::Util qw(decode);
|
||||
use ISO::639_1;
|
||||
use Digest::MD5 'md5';
|
||||
|
||||
sub register {
|
||||
my ($self, $app) = @_;
|
||||
@@ -258,6 +259,18 @@ sub _is_wm_selected {
|
||||
return ($wm eq $c->config('watermark_default')) ? 'selected="selected"' : '';
|
||||
}
|
||||
|
||||
sub _key_from_key {
|
||||
my $key = shift;
|
||||
|
||||
# Key size for Blowfish is 56
|
||||
my $ks = 56;
|
||||
my $material = md5($key);
|
||||
while (length($material) < $ks) {
|
||||
$material .= md5($material);
|
||||
}
|
||||
return substr($material,0,$ks);
|
||||
}
|
||||
|
||||
sub _crypt {
|
||||
my $c = shift;
|
||||
my $upload = shift;
|
||||
@@ -267,10 +280,12 @@ sub _crypt {
|
||||
my $iv = $c->shortener(8);
|
||||
|
||||
my $cipher = Crypt::CBC->new(
|
||||
-key => $key,
|
||||
-cipher => 'Blowfish',
|
||||
-header => 'none',
|
||||
-iv => $iv
|
||||
-key => _key_from_key($key),
|
||||
-cipher => 'Blowfish',
|
||||
-header => 'none',
|
||||
-literal_key => 1,
|
||||
-pbkdf => 'pbkdf2',
|
||||
-iv => $iv
|
||||
);
|
||||
|
||||
$cipher->start('encrypting');
|
||||
@@ -289,16 +304,18 @@ sub _crypt {
|
||||
|
||||
sub _decrypt {
|
||||
my $c = shift;
|
||||
my $key = shift;
|
||||
my $key = _key_from_key(shift);
|
||||
my $file = shift;
|
||||
my $iv = shift;
|
||||
$iv = 'dupajasi' unless $iv;
|
||||
|
||||
my $cipher = Crypt::CBC->new(
|
||||
-key => $key,
|
||||
-cipher => 'Blowfish',
|
||||
-header => 'none',
|
||||
-iv => $iv
|
||||
-key => $key,
|
||||
-cipher => 'Blowfish',
|
||||
-header => 'none',
|
||||
-literal_key => 1,
|
||||
-pbkdf => 'pbkdf2',
|
||||
-iv => $iv
|
||||
);
|
||||
|
||||
$cipher->start('decrypting');
|
||||
|
||||
@@ -135,6 +135,10 @@
|
||||
# optional, defaut is /
|
||||
#prefix => '/',
|
||||
|
||||
# if set to 1, Lutim will try to prevent its use without using the web interface
|
||||
# optional, default is 0
|
||||
#disable_api => 0,
|
||||
|
||||
# choose what database you want to use
|
||||
# valid choices are sqlite and postgresql (all lowercase)
|
||||
# optional, default is sqlite
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/bin/bash
|
||||
FILE=$1
|
||||
if [[ ! -e themes/default/lib/Lutim/I18N/$FILE.po ]]
|
||||
then
|
||||
echo "themes/default/lib/Lutim/I18N/$FILE.po does not exist. Exiting."
|
||||
exit 1
|
||||
else
|
||||
LOCALE=$(echo $FILE | sed -e "s@_@-@g")
|
||||
zanata-cli -q -B push --push-type trans -l $LOCALE
|
||||
fi
|
||||
|
||||
6
t/test.t
6
t/test.t
@@ -81,7 +81,7 @@ $t->get_ok('/css/lutim.css')
|
||||
# Instance settings informations
|
||||
$t->get_ok('/infos')
|
||||
->status_is(200)
|
||||
->json_has('image_magick')
|
||||
->json_has('/image_magick')
|
||||
->json_is(
|
||||
'/always_encrypt' => false,
|
||||
'/broadcast_message' => 'test broadcast message',
|
||||
@@ -96,7 +96,7 @@ $t->get_ok('/infos')
|
||||
my $image = Mojo::File->new($Bin, '..', 'themes', 'default', 'public', 'img', 'Lutim.png')->to_string;
|
||||
$t->post_ok('/' => form => { file => { file => $image }, format => 'json' })
|
||||
->status_is(200)
|
||||
->json_has('msg', 'success')
|
||||
->json_has('/msg', '/success')
|
||||
->json_is('/success' => true, '/msg/filename' => 'Lutim.png')
|
||||
->json_like('/msg/short' => qr#[-_a-zA-Z0-9]{8}#, '/msg/real_short' => qr#[-_a-zA-Z0-9]{8}#, '/msg/token' => qr#[-_a-zA-Z0-9]{24}#);
|
||||
|
||||
@@ -138,7 +138,7 @@ my $token = $raw->json('/msg/token');
|
||||
$t->get_ok('/'.$rshort)
|
||||
->status_is(200);
|
||||
|
||||
$t->get_ok('/d/'.$rshort.'/'.$token, form => { format => 'json' })
|
||||
$t->get_ok('/d/'.$rshort.'/'.$token, form => { _format => 'json' })
|
||||
->status_is('200')
|
||||
->json_is(
|
||||
{
|
||||
|
||||
@@ -12,8 +12,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"PO-Revision-Date: 2020-03-09 16:23+0000\n"
|
||||
"Last-Translator: Luc Didry <luc@framasoft.org>\n"
|
||||
"PO-Revision-Date: 2022-12-24 17:38+0000\n"
|
||||
"Last-Translator: Vri <vrifox@vrifox.cc>\n"
|
||||
"Language-Team: German <https://weblate.framasoft.org/projects/lutim/"
|
||||
"default-theme/de/>\n"
|
||||
"Language: de\n"
|
||||
@@ -21,7 +21,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 3.11.2\n"
|
||||
"X-Generator: Weblate 4.14.1\n"
|
||||
|
||||
#. (7)
|
||||
#. (30)
|
||||
@@ -65,9 +65,8 @@ msgid "An error occured while downloading the image."
|
||||
msgstr "Beim Herunterladen des Bildes ist ein Fehler aufgetreten."
|
||||
|
||||
#: themes/default/templates/zip.html.ep:2
|
||||
#, fuzzy
|
||||
msgid "Archives download"
|
||||
msgstr "Archiv-Download"
|
||||
msgstr "Herunterladen von Archiv"
|
||||
|
||||
#: themes/default/templates/about.html.ep:44 themes/default/templates/myfiles.html.ep:135 themes/default/templates/stats.html.ep:25
|
||||
msgid "Back to homepage"
|
||||
@@ -107,11 +106,11 @@ msgstr "Zähler"
|
||||
|
||||
#: themes/default/templates/stats.html.ep:18
|
||||
msgid "Delay repartition chart for disabled images"
|
||||
msgstr ""
|
||||
msgstr "Diagramm zur Neuaufteilung der Verzögerung für deaktivierte Bilder"
|
||||
|
||||
#: themes/default/templates/stats.html.ep:15
|
||||
msgid "Delay repartition chart for enabled images"
|
||||
msgstr ""
|
||||
msgstr "Diagramm zur Neuaufteilung der Verzögerung für deaktivierte Bilder"
|
||||
|
||||
#: themes/default/templates/index.html.ep:133 themes/default/templates/index.html.ep:165 themes/default/templates/index.html.ep:196 themes/default/templates/myfiles.html.ep:124 themes/default/templates/myfiles.html.ep:45 themes/default/templates/partial/lutim.js.ep:161
|
||||
msgid "Delete at first view?"
|
||||
@@ -162,7 +161,7 @@ msgstr "Verschlüssle das Bild (Lutim behält den Key nicht)."
|
||||
|
||||
#: themes/default/templates/partial/lutim.js.ep:45 themes/default/templates/partial/myfiles.js.ep:113
|
||||
msgid "Error while trying to modify the image."
|
||||
msgstr "Beim bearbeiten des Bildes ist ein Fehler aufgetreten."
|
||||
msgstr "Beim Bearbeiten des Bildes ist ein Fehler aufgetreten."
|
||||
|
||||
#: themes/default/templates/stats.html.ep:10
|
||||
msgid "Evolution of total files"
|
||||
@@ -174,7 +173,7 @@ msgstr "Läuft ab am"
|
||||
|
||||
#: themes/default/templates/myfiles.html.ep:112
|
||||
msgid "Export localStorage data"
|
||||
msgstr ""
|
||||
msgstr "localStorage-Daten exportieren"
|
||||
|
||||
#: themes/default/templates/myfiles.html.ep:121
|
||||
msgid "File name"
|
||||
@@ -190,7 +189,7 @@ msgstr ""
|
||||
|
||||
#: themes/default/templates/partial/navbar.html.ep:80
|
||||
msgid "Fork me!"
|
||||
msgstr "Fork me!"
|
||||
msgstr "Fork mich!"
|
||||
|
||||
#: themes/default/templates/index.html.ep:10 themes/default/templates/index.html.ep:13 themes/default/templates/myfiles.html.ep:60 themes/default/templates/myfiles.html.ep:63
|
||||
msgid "Gallery link"
|
||||
@@ -230,7 +229,7 @@ msgstr "Bild-URL"
|
||||
|
||||
#: lib/Lutim/Command/cron/stats.pm:153 themes/default/templates/raw.html.ep:2
|
||||
msgid "Image delay"
|
||||
msgstr ""
|
||||
msgstr "Bild-Verzögerung"
|
||||
|
||||
#: themes/default/templates/partial/common.js.ep:157
|
||||
msgid "Image deleted"
|
||||
@@ -242,7 +241,7 @@ msgstr "Bild nicht gefunden."
|
||||
|
||||
#: themes/default/templates/myfiles.html.ep:113
|
||||
msgid "Import localStorage data"
|
||||
msgstr ""
|
||||
msgstr "localStorage-Daten importieren"
|
||||
|
||||
#: themes/default/templates/partial/navbar.html.ep:69
|
||||
msgid "Informations"
|
||||
@@ -294,11 +293,11 @@ msgstr "Links zum teilen auf sozialen Netzwerken"
|
||||
|
||||
#: themes/default/templates/login.html.ep:8
|
||||
msgid "Login"
|
||||
msgstr "Login"
|
||||
msgstr "Anmelden"
|
||||
|
||||
#: themes/default/templates/partial/navbar.html.ep:33
|
||||
msgid "Logout"
|
||||
msgstr "Ausloggen"
|
||||
msgstr "Abmelden"
|
||||
|
||||
#: themes/default/templates/zip.html.ep:7
|
||||
msgid ""
|
||||
@@ -335,7 +334,7 @@ msgstr "Meine Bilder"
|
||||
|
||||
#: themes/default/templates/gallery.html.ep:45
|
||||
msgid "Next (arrow right)"
|
||||
msgstr ""
|
||||
msgstr "Nächstes (rechte Pfeiltaste)"
|
||||
|
||||
#: themes/default/templates/partial/myfiles.js.ep:105 themes/default/templates/partial/myfiles.js.ep:132
|
||||
msgid "No limit"
|
||||
@@ -386,7 +385,7 @@ msgstr ""
|
||||
|
||||
#: themes/default/templates/gallery.html.ep:43
|
||||
msgid "Previous (arrow left)"
|
||||
msgstr ""
|
||||
msgstr "Vorheriges (linke Pfeiltaste)"
|
||||
|
||||
#: themes/default/templates/index.html.ep:46 themes/default/templates/index.html.ep:49 themes/default/templates/myfiles.html.ep:96 themes/default/templates/myfiles.html.ep:99
|
||||
msgid "Random image link"
|
||||
@@ -394,7 +393,7 @@ msgstr "Zufälliger Bildlink"
|
||||
|
||||
#: themes/default/templates/stats.html.ep:22
|
||||
msgid "Raw stats"
|
||||
msgstr ""
|
||||
msgstr "Rohe Statistiken"
|
||||
|
||||
#: themes/default/templates/myfiles.html.ep:52
|
||||
msgid "Save changes"
|
||||
@@ -406,7 +405,7 @@ msgstr "Sende ein Bild"
|
||||
|
||||
#: themes/default/templates/login.html.ep:16 themes/default/templates/logout.html.ep:5 themes/default/templates/partial/navbar.html.ep:37
|
||||
msgid "Signin"
|
||||
msgstr "Einloggen"
|
||||
msgstr "Anmelden"
|
||||
|
||||
#: themes/default/templates/index.html.ep:151 themes/default/templates/partial/gallery.js.ep:211 themes/default/templates/partial/lutim.js.ep:176
|
||||
msgid "Something bad happened"
|
||||
@@ -464,10 +463,12 @@ msgid ""
|
||||
"The automatic download process will open a tab in your browser for each link."
|
||||
" You need to allow popups for Lutim."
|
||||
msgstr ""
|
||||
"Das automatische Herunterladen wird für jeden Link einen neuen Tab in deinem "
|
||||
"Browser öffnen. Du musst Pop-Ups für Lutim erlauben."
|
||||
|
||||
#: themes/default/templates/partial/myfiles.js.ep:32
|
||||
msgid "The data has been successfully imported."
|
||||
msgstr ""
|
||||
msgstr "Die Daten wurden erfolgreich importiert."
|
||||
|
||||
#: lib/Lutim/Controller/Image.pm:160 lib/Lutim/Controller/Image.pm:228
|
||||
msgid "The delete token is invalid."
|
||||
@@ -518,7 +519,7 @@ msgstr "Die Zeit bis zum Löschen des Bildes wurde erfolgreich geändert"
|
||||
|
||||
#: themes/default/templates/partial/gallery.js.ep:277
|
||||
msgid "There is XXXX image(s) in the gallery"
|
||||
msgstr ""
|
||||
msgstr "Es gibt XXXX Bild(er) in der Galerie"
|
||||
|
||||
#. ($c->config->{contact})
|
||||
#: lib/Lutim/Controller/Image.pm:485
|
||||
@@ -529,11 +530,11 @@ msgstr ""
|
||||
|
||||
#: themes/default/templates/gallery.html.ep:30
|
||||
msgid "Toggle fullscreen"
|
||||
msgstr ""
|
||||
msgstr "Vollbild umschalten"
|
||||
|
||||
#: themes/default/templates/partial/navbar.html.ep:8
|
||||
msgid "Toggle navigation"
|
||||
msgstr ""
|
||||
msgstr "Navigation umschalten"
|
||||
|
||||
#: lib/Lutim/Command/cron/stats.pm:162 themes/default/templates/raw.html.ep:11
|
||||
msgid "Total"
|
||||
@@ -621,9 +622,9 @@ msgid ""
|
||||
"do it via <a href=\"https://www.tipeee.com/fiat-tux\">Tipeee</a> or via <a "
|
||||
"href=\"https://liberapay.com/sky/\">Liberapay</a>."
|
||||
msgstr ""
|
||||
"Ja, ist es! Auf der anderen Seite kannst du den Entwickler via <a href="
|
||||
"\"https://www.tipeee.com/fiat-tux\">Tipeee</a> oder <a href=\"https://"
|
||||
"liberapay.com/sky/\">Liberapay</a> unterstützen."
|
||||
"Ja, ist es! Jedoch kannst du den Entwickler via <a href=\"https://www.tipeee."
|
||||
"com/fiat-tux\">Tipeee</a> oder <a href=\"https://liberapay.com/sky/\""
|
||||
">Liberapay</a> unterstützen."
|
||||
|
||||
#: themes/default/templates/zip.html.ep:6
|
||||
msgid "You asked to download a zip archive for too much files."
|
||||
@@ -677,7 +678,7 @@ msgstr "auf"
|
||||
|
||||
#: themes/default/templates/about.html.ep:39
|
||||
msgid "paste image to upload ability"
|
||||
msgstr ""
|
||||
msgstr "Bild zum Hochladen einfügen-Funktion"
|
||||
|
||||
#: themes/default/templates/about.html.ep:41
|
||||
msgid "russian translation"
|
||||
@@ -690,3 +691,21 @@ msgstr "spanische Übersetzung"
|
||||
#: themes/default/templates/about.html.ep:28
|
||||
msgid "webapp developer"
|
||||
msgstr "Webapp-Entwickler"
|
||||
|
||||
#: themes/default/templates/about.html.ep:24
|
||||
msgid "For more details, see the <a href=\"https://framagit.org/fiat-tux/hat-softwares/lutim\">homepage of the project</a>."
|
||||
msgstr ""
|
||||
"Für weitere Details besuche die <a href=\"https://framagit.org/fiat-tux/"
|
||||
"hat-softwares/lutim\">Website des Projekts</a>."
|
||||
|
||||
#: themes/default/templates/index.html.ep:174 themes/default/templates/index.html.ep:218
|
||||
msgid "Single watermark"
|
||||
msgstr "Einzelnes Wasserzeichen"
|
||||
|
||||
#: themes/default/templates/index.html.ep:171 themes/default/templates/index.html.ep:215
|
||||
msgid "Tiling watermark"
|
||||
msgstr "Gekacheltes Wasserzeichen"
|
||||
|
||||
#: themes/default/templates/index.html.ep:177 themes/default/templates/index.html.ep:221
|
||||
msgid "No watermark"
|
||||
msgstr "Kein Wasserzeichen"
|
||||
|
||||
@@ -11,8 +11,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"PO-Revision-Date: 2020-03-09 16:23+0000\n"
|
||||
"Last-Translator: Luc Didry <luc@framasoft.org>\n"
|
||||
"PO-Revision-Date: 2021-04-24 11:14+0000\n"
|
||||
"Last-Translator: Berto Te <ateira@3fpj.com>\n"
|
||||
"Language-Team: Spanish <https://weblate.framasoft.org/projects/lutim/"
|
||||
"default-theme/es/>\n"
|
||||
"Language: es\n"
|
||||
@@ -20,7 +20,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 3.11.2\n"
|
||||
"X-Generator: Weblate 4.5.1\n"
|
||||
|
||||
#. (7)
|
||||
#. (30)
|
||||
@@ -646,7 +646,7 @@ msgstr "Ha sido desconectado con éxito."
|
||||
|
||||
#: themes/default/templates/gallery.html.ep:31
|
||||
msgid "Zoom in/out"
|
||||
msgstr "Zoom in/out"
|
||||
msgstr "Zoom aumentar / reducir"
|
||||
|
||||
#: themes/default/templates/about.html.ep:27
|
||||
msgid "and on"
|
||||
@@ -693,3 +693,15 @@ msgid "For more details, see the <a href=\"https://framagit.org/fiat-tux/hat-sof
|
||||
msgstr ""
|
||||
"Para más detalles, vea la <a href=\"https://framagit.org/fiat-tux/"
|
||||
"hat-softwares/lutim\">página del proyecto</a>."
|
||||
|
||||
#: themes/default/templates/index.html.ep:171 themes/default/templates/index.html.ep:215
|
||||
msgid "Tiling watermark"
|
||||
msgstr "Marca de agua en mosaico"
|
||||
|
||||
#: themes/default/templates/index.html.ep:174 themes/default/templates/index.html.ep:218
|
||||
msgid "Single watermark"
|
||||
msgstr "Marca de agua única"
|
||||
|
||||
#: themes/default/templates/index.html.ep:177 themes/default/templates/index.html.ep:221
|
||||
msgid "No watermark"
|
||||
msgstr "Sin marca de agua"
|
||||
|
||||
637
themes/default/lib/Lutim/I18N/hr.po
Normal file
637
themes/default/lib/Lutim/I18N/hr.po
Normal file
@@ -0,0 +1,637 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"PO-Revision-Date: 2022-07-24 18:36+0000\n"
|
||||
"Last-Translator: Milo Ivir <mail@milotype.de>\n"
|
||||
"Language-Team: Croatian <https://weblate.framasoft.org/projects/lutim/"
|
||||
"default-theme/hr/>\n"
|
||||
"Language: hr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||
"X-Generator: Weblate 4.13.1\n"
|
||||
|
||||
#. (7)
|
||||
#. (30)
|
||||
#. ($delay)
|
||||
#. (config('max_delay')
|
||||
#: lib/Lutim/Command/cron/stats.pm:156 lib/Lutim/Command/cron/stats.pm:157 lib/Lutim/Command/cron/stats.pm:170 lib/Lutim/Command/cron/stats.pm:171 lib/Lutim/Command/cron/stats.pm:187 lib/Lutim/Command/cron/stats.pm:188 themes/default/templates/myfiles.html.ep:24 themes/default/templates/myfiles.html.ep:33 themes/default/templates/myfiles.html.ep:34 themes/default/templates/partial/for_my_delay.html.ep:13 themes/default/templates/partial/for_my_delay.html.ep:14 themes/default/templates/partial/for_my_delay.html.ep:4 themes/default/templates/partial/lutim.js.ep:140 themes/default/templates/partial/lutim.js.ep:149 themes/default/templates/partial/lutim.js.ep:150 themes/default/templates/partial/raw.js.ep:23 themes/default/templates/partial/raw.js.ep:24 themes/default/templates/partial/raw.js.ep:6 themes/default/templates/partial/raw.js.ep:7 themes/default/templates/raw.html.ep:8 themes/default/templates/raw.html.ep:9
|
||||
msgid "%1 days"
|
||||
msgstr "%1 dana"
|
||||
|
||||
#. ($total)
|
||||
#: themes/default/templates/stats.html.ep:2
|
||||
msgid "%1 sent images on this instance from beginning."
|
||||
msgstr "Broj poslanih slika u ovoj instanci od početka: %1."
|
||||
|
||||
#: themes/default/templates/index.html.ep:228
|
||||
msgid "-or-"
|
||||
msgstr "-ili-"
|
||||
|
||||
#: lib/Lutim.pm:342 lib/Lutim/Command/cron/stats.pm:158 lib/Lutim/Command/cron/stats.pm:172 lib/Lutim/Command/cron/stats.pm:189 themes/default/templates/index.html.ep:5 themes/default/templates/myfiles.html.ep:5 themes/default/templates/partial/raw.js.ep:25 themes/default/templates/partial/raw.js.ep:8 themes/default/templates/raw.html.ep:10
|
||||
msgid "1 year"
|
||||
msgstr "1 godina"
|
||||
|
||||
#: lib/Lutim.pm:341 lib/Lutim/Command/cron/stats.pm:155 lib/Lutim/Command/cron/stats.pm:169 lib/Lutim/Command/cron/stats.pm:186 themes/default/templates/index.html.ep:4 themes/default/templates/myfiles.html.ep:33 themes/default/templates/myfiles.html.ep:4 themes/default/templates/partial/for_my_delay.html.ep:13 themes/default/templates/partial/lutim.js.ep:149 themes/default/templates/partial/raw.js.ep:22 themes/default/templates/partial/raw.js.ep:5 themes/default/templates/raw.html.ep:7
|
||||
msgid "24 hours"
|
||||
msgstr "24 sata"
|
||||
|
||||
#: themes/default/templates/partial/myfiles.js.ep:210
|
||||
msgid ": Error while trying to get the counter."
|
||||
msgstr ": Greška u dohvaćanju brojača."
|
||||
|
||||
#: themes/default/templates/partial/navbar.html.ep:63
|
||||
msgid "About"
|
||||
msgstr "O programu"
|
||||
|
||||
#: lib/Lutim/Command/cron/stats.pm:151 themes/default/templates/raw.html.ep:3
|
||||
msgid "Active images"
|
||||
msgstr "Aktivne slike"
|
||||
|
||||
#: lib/Lutim/Controller/Image.pm:329
|
||||
msgid "An error occured while downloading the image."
|
||||
msgstr "Dogodila se greška prilikom preuzimanja slike."
|
||||
|
||||
#: themes/default/templates/zip.html.ep:2
|
||||
msgid "Archives download"
|
||||
msgstr "Preuzimanje arhiva"
|
||||
|
||||
#: themes/default/templates/about.html.ep:44 themes/default/templates/myfiles.html.ep:129 themes/default/templates/stats.html.ep:25
|
||||
msgid "Back to homepage"
|
||||
msgstr "Natrag na web-stranicu"
|
||||
|
||||
#: themes/default/templates/index.html.ep:231 themes/default/templates/index.html.ep:232
|
||||
msgid "Click to open the file browser"
|
||||
msgstr "Pritisni za otvaranje preglednika datoteka"
|
||||
|
||||
#: themes/default/templates/myfiles.html.ep:51
|
||||
msgid "Close"
|
||||
msgstr "Zatvori"
|
||||
|
||||
#: themes/default/templates/gallery.html.ep:29
|
||||
msgid "Close (Esc)"
|
||||
msgstr "Zatvori (Esc)"
|
||||
|
||||
#: themes/default/templates/about.html.ep:30
|
||||
msgid "Contributors"
|
||||
msgstr "Doprinositelji"
|
||||
|
||||
#: themes/default/templates/partial/common.js.ep:113 themes/default/templates/partial/common.js.ep:93
|
||||
msgid "Copied to clipboard"
|
||||
msgstr "Kopirano u međuspremnik"
|
||||
|
||||
#: themes/default/templates/partial/lutim.js.ep:215 themes/default/templates/partial/lutim.js.ep:278 themes/default/templates/partial/lutim.js.ep:364
|
||||
msgid "Copy all view links to clipboard"
|
||||
msgstr "Kopiraj sve poveznice prikaza u međuspremnik"
|
||||
|
||||
#: themes/default/templates/index.html.ep:105 themes/default/templates/index.html.ep:16 themes/default/templates/index.html.ep:32 themes/default/templates/index.html.ep:48 themes/default/templates/index.html.ep:81 themes/default/templates/index.html.ep:89 themes/default/templates/index.html.ep:97 themes/default/templates/myfiles.html.ep:66 themes/default/templates/myfiles.html.ep:82 themes/default/templates/myfiles.html.ep:98 themes/default/templates/partial/common.js.ep:186 themes/default/templates/partial/lutim.js.ep:106 themes/default/templates/partial/lutim.js.ep:121 themes/default/templates/partial/lutim.js.ep:80 themes/default/templates/partial/lutim.js.ep:92 themes/default/templates/partial/myfiles.js.ep:172
|
||||
msgid "Copy to clipboard"
|
||||
msgstr "Kopiraj u međuspremnik"
|
||||
|
||||
#: themes/default/templates/myfiles.html.ep:117
|
||||
msgid "Counter"
|
||||
msgstr "Brojač"
|
||||
|
||||
#: themes/default/templates/stats.html.ep:18
|
||||
msgid "Delay repartition chart for disabled images"
|
||||
msgstr "Dijagram odgode raspodjele za isključene slike"
|
||||
|
||||
#: themes/default/templates/stats.html.ep:15
|
||||
msgid "Delay repartition chart for enabled images"
|
||||
msgstr "Dijagram odgode raspodjele za uključene slike"
|
||||
|
||||
#: themes/default/templates/index.html.ep:127 themes/default/templates/index.html.ep:159 themes/default/templates/index.html.ep:203 themes/default/templates/myfiles.html.ep:118 themes/default/templates/myfiles.html.ep:45 themes/default/templates/partial/lutim.js.ep:161
|
||||
msgid "Delete at first view?"
|
||||
msgstr "Izbrisati pri prvom prikazu?"
|
||||
|
||||
#: lib/Lutim/Command/cron/stats.pm:152 themes/default/templates/raw.html.ep:4
|
||||
msgid "Deleted images"
|
||||
msgstr "Izbrisane slike"
|
||||
|
||||
#: lib/Lutim/Command/cron/stats.pm:153 themes/default/templates/raw.html.ep:5
|
||||
msgid "Deleted images in 30 days"
|
||||
msgstr "Izbrisane slike u 30 dana"
|
||||
|
||||
#: themes/default/templates/index.html.ep:110 themes/default/templates/myfiles.html.ep:121 themes/default/templates/partial/common.js.ep:178 themes/default/templates/partial/common.js.ep:181
|
||||
msgid "Deletion link"
|
||||
msgstr "Poveznica za brisanje"
|
||||
|
||||
#: themes/default/templates/gallery.html.ep:10
|
||||
msgid "Download all images"
|
||||
msgstr "Preuzmi sve slike"
|
||||
|
||||
#: themes/default/templates/index.html.ep:93 themes/default/templates/index.html.ep:95 themes/default/templates/partial/lutim.js.ep:102 themes/default/templates/partial/lutim.js.ep:98
|
||||
msgid "Download link"
|
||||
msgstr "Poveznica za preuzimanje"
|
||||
|
||||
#: themes/default/templates/index.html.ep:26 themes/default/templates/index.html.ep:28 themes/default/templates/myfiles.html.ep:76 themes/default/templates/myfiles.html.ep:78
|
||||
msgid "Download zip link"
|
||||
msgstr "Poveznica za preuzimanje zip-a"
|
||||
|
||||
#: themes/default/templates/index.html.ep:227
|
||||
msgid "Drag & drop images here"
|
||||
msgstr "Povuci i ispusti slike ovamo"
|
||||
|
||||
#: themes/default/templates/about.html.ep:7
|
||||
msgid "Drag and drop an image in the appropriate area or use the traditional way to send files and Lutim will provide you four URLs. One to view the image, an other to directly download it, one you can use on social networks and a last to delete the image when you want."
|
||||
msgstr ""
|
||||
"Povuci i ispusti sliku u odgovarajuće područje ili koristi tradicionalni "
|
||||
"način slanja datoteka i Lutim će ti dati četiri URL-a. Jedan za pregled "
|
||||
"slike, drugi za izravno preuzimanje, jedan koji možeš koristiti na "
|
||||
"društvenim mrežama i zadnji za brisanje slike kada želiš."
|
||||
|
||||
#: themes/default/templates/index.html.ep:162 themes/default/templates/index.html.ep:206
|
||||
msgid "Encrypt the image (Lutim does not keep the key)."
|
||||
msgstr "Šifriraj sliku (Lutim ne čuva ključ)."
|
||||
|
||||
#: themes/default/templates/partial/lutim.js.ep:45 themes/default/templates/partial/myfiles.js.ep:128
|
||||
msgid "Error while trying to modify the image."
|
||||
msgstr "Greška prilikom pokušaja stvaranja promjena u slici."
|
||||
|
||||
#: themes/default/templates/stats.html.ep:10
|
||||
msgid "Evolution of total files"
|
||||
msgstr "Razvoj ukupnog broja datoteka"
|
||||
|
||||
#: themes/default/templates/myfiles.html.ep:120
|
||||
msgid "Expires at"
|
||||
msgstr "Isteče"
|
||||
|
||||
#: themes/default/templates/myfiles.html.ep:106
|
||||
msgid "Export localStorage data"
|
||||
msgstr "Izvezi podatke lokalnog spremišta"
|
||||
|
||||
#: themes/default/templates/myfiles.html.ep:115
|
||||
msgid "File name"
|
||||
msgstr "Ime datoteke"
|
||||
|
||||
#: themes/default/templates/about.html.ep:24
|
||||
msgid "For more details, see the <a href=\"https://framagit.org/fiat-tux/hat-softwares/lutim\">homepage of the project</a>."
|
||||
msgstr ""
|
||||
"Pogledaj detalje na <a href=\"https://framagit.org/fiat-tux/hat-softwares/"
|
||||
"lutim\">web-stranici projekta</a>."
|
||||
|
||||
#: themes/default/templates/partial/navbar.html.ep:66
|
||||
msgid "Fork me!"
|
||||
msgstr "Kopiraj granu!"
|
||||
|
||||
#: themes/default/templates/index.html.ep:10 themes/default/templates/index.html.ep:12 themes/default/templates/myfiles.html.ep:60 themes/default/templates/myfiles.html.ep:62
|
||||
msgid "Gallery link"
|
||||
msgstr "Poveznica galerije"
|
||||
|
||||
#: themes/default/templates/partial/common.js.ep:116 themes/default/templates/partial/common.js.ep:134
|
||||
msgid "Hit Ctrl+C, then Enter to copy the short link"
|
||||
msgstr "Pritisni Ctrl+C, zatim Enter za kopiranje kratke poveznice"
|
||||
|
||||
#: themes/default/templates/layouts/default.html.ep:47
|
||||
msgid "Homepage"
|
||||
msgstr "Web-stranica"
|
||||
|
||||
#: themes/default/templates/about.html.ep:20
|
||||
msgid "How do you pronounce Lutim?"
|
||||
msgstr "Kako se izgovara Lutim?"
|
||||
|
||||
#: themes/default/templates/about.html.ep:6
|
||||
msgid "How does it work?"
|
||||
msgstr "Kako radi?"
|
||||
|
||||
#: themes/default/templates/about.html.ep:18
|
||||
msgid "How to report an image?"
|
||||
msgstr "Kako prijaviti sliku?"
|
||||
|
||||
#: themes/default/templates/about.html.ep:14
|
||||
msgid "If the files are deleted if you ask it while posting it, their SHA512 footprint are retained."
|
||||
msgstr ""
|
||||
"Ako se datoteke izbrišu ako to zatražiš dok ih objavljuješ, njihov SHA512 "
|
||||
"otisak se zadržava."
|
||||
|
||||
#: themes/default/templates/index.html.ep:188 themes/default/templates/index.html.ep:241
|
||||
msgid "Image URL"
|
||||
msgstr "URL adresa slike"
|
||||
|
||||
#: lib/Lutim/Command/cron/stats.pm:150 themes/default/templates/raw.html.ep:2
|
||||
msgid "Image delay"
|
||||
msgstr "Kašnjenje slike"
|
||||
|
||||
#: themes/default/templates/partial/common.js.ep:157
|
||||
msgid "Image deleted"
|
||||
msgstr "Slika izbrisana"
|
||||
|
||||
#: lib/Lutim/Controller/Image.pm:799
|
||||
msgid "Image not found."
|
||||
msgstr "Slika nije pronađena."
|
||||
|
||||
#: themes/default/templates/myfiles.html.ep:107
|
||||
msgid "Import localStorage data"
|
||||
msgstr "Uvezi podatke lokalnog spremišta"
|
||||
|
||||
#: themes/default/templates/partial/navbar.html.ep:55
|
||||
msgid "Informations"
|
||||
msgstr "Informacije"
|
||||
|
||||
#: themes/default/templates/partial/navbar.html.ep:25
|
||||
msgid "Install webapp"
|
||||
msgstr "Instaliraj web-aplikaciju"
|
||||
|
||||
#: themes/default/templates/partial/navbar.html.ep:21
|
||||
msgid "Instance's statistics"
|
||||
msgstr "Statistika instance"
|
||||
|
||||
#: themes/default/templates/about.html.ep:11
|
||||
msgid "Is it really anonymous?"
|
||||
msgstr "Je li stvarno anonimno?"
|
||||
|
||||
#: themes/default/templates/about.html.ep:9
|
||||
msgid "Is it really free (as in free beer)?"
|
||||
msgstr "Je li se stvarno može besplatno koristiti?"
|
||||
|
||||
#: themes/default/templates/about.html.ep:21
|
||||
msgid "Juste like you pronounce the French word <a href=\"https://fr.wikipedia.org/wiki/Lutin\">lutin</a> (/ly.tɛ̃/)."
|
||||
msgstr ""
|
||||
"Isto kao izgovaranje francuske riječi <a href=\"https://fr.wikipedia.org/"
|
||||
"wiki/Lutin\">lutin</a> (/ly.tɛ̃/)."
|
||||
|
||||
#: themes/default/templates/index.html.ep:165 themes/default/templates/index.html.ep:209
|
||||
msgid "Keep EXIF tags"
|
||||
msgstr "Zadrži EXIF oznake"
|
||||
|
||||
#: themes/default/templates/partial/navbar.html.ep:43
|
||||
msgid "Language"
|
||||
msgstr "Jezik"
|
||||
|
||||
#: themes/default/templates/index.html.ep:130 themes/default/templates/index.html.ep:191 themes/default/templates/index.html.ep:244 themes/default/templates/partial/lutim.js.ep:165
|
||||
msgid "Let's go!"
|
||||
msgstr "Kreni!"
|
||||
|
||||
#: themes/default/templates/partial/navbar.html.ep:60
|
||||
msgid "License:"
|
||||
msgstr "Licenca:"
|
||||
|
||||
#: themes/default/templates/index.html.ep:101 themes/default/templates/index.html.ep:103 themes/default/templates/partial/lutim.js.ep:112 themes/default/templates/partial/lutim.js.ep:116
|
||||
msgid "Link for share on social networks"
|
||||
msgstr "Poveznica za dijeljenje na društvenim mrežama"
|
||||
|
||||
#: themes/default/templates/login.html.ep:8
|
||||
msgid "Login"
|
||||
msgstr "Prijava"
|
||||
|
||||
#: themes/default/templates/partial/navbar.html.ep:33
|
||||
msgid "Logout"
|
||||
msgstr "Odjava"
|
||||
|
||||
#: themes/default/templates/zip.html.ep:7
|
||||
msgid "Lutim can't zip so many images at once, so it splitted your demand in multiple URLs."
|
||||
msgstr ""
|
||||
"Lutim ne može komprimirati toliko slika odjednom. Tvoj zahtjev je stoga "
|
||||
"podijeljen na više URL-ova."
|
||||
|
||||
#: themes/default/templates/about.html.ep:4
|
||||
msgid "Lutim is a free (as in free beer) and anonymous image hosting service. It's also the name of the free (as in free speech) software which provides this service."
|
||||
msgstr ""
|
||||
"Lutim je besplatna i anonimna hosting usluga za slike. To je također ime "
|
||||
"slobodnog softvera koji pruža ovu uslugu."
|
||||
|
||||
#: themes/default/templates/about.html.ep:25
|
||||
msgid "Main developers"
|
||||
msgstr "Glavni programeri"
|
||||
|
||||
#: themes/default/templates/index.html.ep:85 themes/default/templates/index.html.ep:87 themes/default/templates/partial/lutim.js.ep:86 themes/default/templates/partial/lutim.js.ep:89
|
||||
msgid "Markdown syntax"
|
||||
msgstr "Markdown sintaksa"
|
||||
|
||||
#: themes/default/templates/partial/myfiles.js.ep:179
|
||||
msgid "Modify expiration delay"
|
||||
msgstr "Promijeni odgodu isteka"
|
||||
|
||||
#: themes/default/templates/myfiles.html.ep:7 themes/default/templates/partial/navbar.html.ep:18
|
||||
msgid "My images"
|
||||
msgstr "Moje slike"
|
||||
|
||||
#: themes/default/templates/gallery.html.ep:45
|
||||
msgid "Next (arrow right)"
|
||||
msgstr "Sljedeće (desna strelica)"
|
||||
|
||||
#: themes/default/templates/partial/myfiles.js.ep:120 themes/default/templates/partial/myfiles.js.ep:162
|
||||
msgid "No limit"
|
||||
msgstr "Bez ograničenja"
|
||||
|
||||
#: themes/default/templates/index.html.ep:177 themes/default/templates/index.html.ep:221
|
||||
msgid "No watermark"
|
||||
msgstr "Bez vodenog žiga"
|
||||
|
||||
#: themes/default/templates/index.html.ep:190 themes/default/templates/index.html.ep:236
|
||||
msgid "Only images are allowed"
|
||||
msgstr "Dozvoljene su samo slike"
|
||||
|
||||
#: themes/default/templates/myfiles.html.ep:11
|
||||
msgid "Only the images sent with this browser will be listed here. The details are stored in localStorage: if you delete your localStorage data, you'll loose these details."
|
||||
msgstr ""
|
||||
"Ovdje će biti navedene samo slike poslane ovim preglednikom. Detalji se "
|
||||
"spremaju u lokalno spremište: ako izbrišeš svoje podatke lokalnog spremišta, "
|
||||
"izgubit ćeš te detalje."
|
||||
|
||||
#: themes/default/templates/about.html.ep:16
|
||||
msgid "Only the uploader! (well, only if he's the only owner of the images' rights before the upload)"
|
||||
msgstr ""
|
||||
"Samo prenositelj! (zapravo, samo ako je on jedini vlasnik prava na slike "
|
||||
"prije prijenosa)"
|
||||
|
||||
#: themes/default/templates/login.html.ep:12
|
||||
msgid "Password"
|
||||
msgstr "Lozinka"
|
||||
|
||||
#: themes/default/templates/zip.html.ep:12
|
||||
msgid "Please click on each URL to download the different zip files."
|
||||
msgstr "Pritisni svaki URL za preuzimanje zip datoteka."
|
||||
|
||||
#. (config('contact')
|
||||
#: themes/default/templates/about.html.ep:19
|
||||
msgid "Please contact the administrator: %1"
|
||||
msgstr "Kontaktiraj administratora: %1"
|
||||
|
||||
#: lib/Lutim/Controller/Authent.pm:36
|
||||
msgid "Please, check your credentials: unable to authenticate."
|
||||
msgstr "Provjeri svoje podatke autentifikacije: autentifikacija je neuspjela."
|
||||
|
||||
#: themes/default/templates/gallery.html.ep:43
|
||||
msgid "Previous (arrow left)"
|
||||
msgstr "Prethodno (lijeva strelica)"
|
||||
|
||||
#: themes/default/templates/index.html.ep:42 themes/default/templates/index.html.ep:44 themes/default/templates/myfiles.html.ep:92 themes/default/templates/myfiles.html.ep:94
|
||||
msgid "Random image link"
|
||||
msgstr "Poveznica slučajne slike"
|
||||
|
||||
#: themes/default/templates/stats.html.ep:22
|
||||
msgid "Raw stats"
|
||||
msgstr "Neobrađena statistika"
|
||||
|
||||
#: themes/default/templates/myfiles.html.ep:52
|
||||
msgid "Save changes"
|
||||
msgstr "Spremi promjene"
|
||||
|
||||
#: themes/default/templates/index.html.ep:183
|
||||
msgid "Send an image"
|
||||
msgstr "Pošalji sliku"
|
||||
|
||||
#: themes/default/templates/login.html.ep:16 themes/default/templates/logout.html.ep:5 themes/default/templates/partial/navbar.html.ep:37
|
||||
msgid "Signin"
|
||||
msgstr "Prijava"
|
||||
|
||||
#: themes/default/templates/index.html.ep:174 themes/default/templates/index.html.ep:218
|
||||
msgid "Single watermark"
|
||||
msgstr "Jedan vodeni žig"
|
||||
|
||||
#: themes/default/templates/index.html.ep:145 themes/default/templates/partial/gallery.js.ep:211 themes/default/templates/partial/lutim.js.ep:176
|
||||
msgid "Something bad happened"
|
||||
msgstr "Dogodila se greška"
|
||||
|
||||
#. ($c->config('contact')
|
||||
#: lib/Lutim/Controller/Image.pm:806
|
||||
msgid "Something went wrong when creating the zip file. Try again later or contact the administrator (%1)."
|
||||
msgstr ""
|
||||
"Dogodila se greška prilikom izrade zip datoteke. Pokušaj ponovo kasnije ili "
|
||||
"kontaktiraj administratora (%1)."
|
||||
|
||||
#: themes/default/templates/about.html.ep:13
|
||||
msgid "The IP address of the image's sender is retained for a delay which depends of the administrator's choice (for the official instance, which is located in France, it's one year)."
|
||||
msgstr ""
|
||||
"IP adresa pošiljatelja slike zadržava se odgodom koja ovisi o izboru "
|
||||
"administratora (za službenu instancu, koja se nalazi u Francuskoj, to je "
|
||||
"godinu dana)."
|
||||
|
||||
#: themes/default/templates/about.html.ep:23
|
||||
msgid "The Lutim software is a <a href=\"http://en.wikipedia.org/wiki/Free_software\">free software</a>, which allows you to download and install it on you own server. Have a look at the <a href=\"https://www.gnu.org/licenses/agpl-3.0.html\">AGPL</a> to see what you can do."
|
||||
msgstr ""
|
||||
"Softver Lutim je <a href=\"http://en.wikipedia.org/wiki/Free_software\""
|
||||
">slobodan softver</a> koji omogućuje preuzmanje i instaliranje softvera na "
|
||||
"vlastiti poslužitelj. Pogledaj <a href=\"https://www.gnu.org/licenses/agpl-3."
|
||||
"0.html\">AGPL</a> za prikaz mogućnosti."
|
||||
|
||||
#: lib/Lutim/Controller/Image.pm:348
|
||||
msgid "The URL is not valid."
|
||||
msgstr "URL nije ispravan."
|
||||
|
||||
#: themes/default/templates/zip.html.ep:16
|
||||
msgid "The automatic download process will open a tab in your browser for each link. You need to allow popups for Lutim."
|
||||
msgstr ""
|
||||
"Automatski postupak preuzimanja otvorit će karticu u tvom pregledniku za "
|
||||
"svaku poveznicu. Moraš dozvoliti skočne prozore za Lutim."
|
||||
|
||||
#: themes/default/templates/partial/myfiles.js.ep:32
|
||||
msgid "The data has been successfully imported."
|
||||
msgstr "Podaci su uspješno uvezeni."
|
||||
|
||||
#: lib/Lutim/Controller/Image.pm:160 lib/Lutim/Controller/Image.pm:228
|
||||
msgid "The delete token is invalid."
|
||||
msgstr "Token brisanja je neispravan."
|
||||
|
||||
#. ($upload->filename)
|
||||
#: lib/Lutim/Controller/Image.pm:531
|
||||
msgid "The file %1 is not an image."
|
||||
msgstr "Datoteka %1 nije slika."
|
||||
|
||||
#. ($tx->res->max_message_size)
|
||||
#. ($c->req->max_message_size)
|
||||
#. (config('max_file_size')
|
||||
#: lib/Lutim/Controller/Image.pm:312 lib/Lutim/Controller/Image.pm:381 themes/default/templates/partial/lutim.js.ep:249
|
||||
msgid "The file exceed the size limit (%1)"
|
||||
msgstr "Datoteka je prekoračila granicu (%1)"
|
||||
|
||||
#: themes/default/templates/stats.html.ep:12
|
||||
msgid "The graph's datas are not updated in real-time."
|
||||
msgstr "Podaci dijagrama se ne aktualiziraju se u stvarnom vremenu."
|
||||
|
||||
#. ($image->filename)
|
||||
#: lib/Lutim/Controller/Image.pm:230
|
||||
msgid "The image %1 has already been deleted."
|
||||
msgstr "Slika %1 je već izbrisana."
|
||||
|
||||
#. ($image->filename)
|
||||
#: lib/Lutim/Controller/Image.pm:239 lib/Lutim/Controller/Image.pm:244
|
||||
msgid "The image %1 has been successfully deleted"
|
||||
msgstr "Slika %1 je uspješno izbrisana"
|
||||
|
||||
#: themes/default/templates/index.html.ep:57
|
||||
msgid "The images are encrypted on the server (Lutim does not keep the key)."
|
||||
msgstr "Slike su šifrirane na poslužitelju (Lutim ne čuva ključ)."
|
||||
|
||||
#: themes/default/templates/about.html.ep:5
|
||||
msgid "The images you post on Lutim can be stored indefinitely or be deleted at first view or after a delay selected from those proposed."
|
||||
msgstr ""
|
||||
"Slike koje objeviš na Lutimu mogu se spremiti na neodređeno vrijeme ili se "
|
||||
"mogu izbrisati pri prvom pregledu ili nakon odabrane odgode od predloženih."
|
||||
|
||||
#: lib/Lutim/Controller/Image.pm:168
|
||||
msgid "The image’s delay has been successfully modified"
|
||||
msgstr "Kašnjenje slike je uspješno promijenjeno"
|
||||
|
||||
#: themes/default/templates/partial/gallery.js.ep:277
|
||||
msgid "There is XXXX image(s) in the gallery"
|
||||
msgstr "Galerija sadrži XXXX slika"
|
||||
|
||||
#. ($c->config->{contact})
|
||||
#: lib/Lutim/Controller/Image.pm:528
|
||||
msgid "There is no more available URL. Retry or contact the administrator. %1"
|
||||
msgstr ""
|
||||
"Nema više dostupnog URL-a. Pokušaj ponovo ili kontaktiraj administratora. %1"
|
||||
|
||||
#: themes/default/templates/index.html.ep:171 themes/default/templates/index.html.ep:215
|
||||
msgid "Tiling watermark"
|
||||
msgstr "Pločasti vodeni žig"
|
||||
|
||||
#: themes/default/templates/gallery.html.ep:30
|
||||
msgid "Toggle fullscreen"
|
||||
msgstr "Uključi/isključi cjeloekranski prikaz"
|
||||
|
||||
#: themes/default/templates/partial/navbar.html.ep:8
|
||||
msgid "Toggle navigation"
|
||||
msgstr "Uključi/isključi navigaciju"
|
||||
|
||||
#: lib/Lutim/Command/cron/stats.pm:159 themes/default/templates/raw.html.ep:11
|
||||
msgid "Total"
|
||||
msgstr "Ukupno"
|
||||
|
||||
#: themes/default/templates/index.html.ep:72 themes/default/templates/partial/lutim.js.ep:17
|
||||
msgid "Tweet it!"
|
||||
msgstr "Pošalji tweet!"
|
||||
|
||||
#: themes/default/templates/partial/common.js.ep:110 themes/default/templates/partial/common.js.ep:90
|
||||
msgid "Unable to copy to clipboard"
|
||||
msgstr "Neuspjelo kopiranje u međuspremink"
|
||||
|
||||
#. ($short)
|
||||
#: lib/Lutim/Controller/Image.pm:108 lib/Lutim/Controller/Image.pm:202 lib/Lutim/Controller/Image.pm:273
|
||||
msgid "Unable to find the image %1."
|
||||
msgstr "Neuspjelo pronalaženje slike %1."
|
||||
|
||||
#: lib/Lutim/Controller/Image.pm:617 lib/Lutim/Controller/Image.pm:662 lib/Lutim/Controller/Image.pm:703 lib/Lutim/Controller/Image.pm:746 lib/Lutim/Controller/Image.pm:758 lib/Lutim/Controller/Image.pm:769 lib/Lutim/Controller/Image.pm:796 lib/Lutim/Plugin/Helpers.pm:89
|
||||
msgid "Unable to find the image: it has been deleted."
|
||||
msgstr "Neuspjelo pronalaženje slike: slika je izbrisana."
|
||||
|
||||
#: lib/Lutim/Controller/Image.pm:145
|
||||
msgid "Unable to get counter"
|
||||
msgstr "Neuspjelo dohvaćanje brojača"
|
||||
|
||||
#: themes/default/templates/about.html.ep:17
|
||||
msgid "Unlike many image sharing services, you don't give us rights on uploaded images."
|
||||
msgstr ""
|
||||
"Za razliku od mnogih usluga za dijeljenje slika, ne daješ nam prava za "
|
||||
"prenesene slike."
|
||||
|
||||
#: themes/default/templates/index.html.ep:187 themes/default/templates/index.html.ep:239
|
||||
msgid "Upload an image with its URL"
|
||||
msgstr "Prenesi sliku s ovim URL-om"
|
||||
|
||||
#: themes/default/templates/myfiles.html.ep:119
|
||||
msgid "Uploaded at"
|
||||
msgstr "Preneseno"
|
||||
|
||||
#: themes/default/templates/stats.html.ep:6
|
||||
msgid "Uploaded files by days"
|
||||
msgstr "Prenesene datoteke po danima"
|
||||
|
||||
#. ($c->app->config('contact')
|
||||
#: lib/Lutim/Plugin/Helpers.pm:222
|
||||
msgid "Uploading is currently disabled, please try later or contact the administrator (%1)."
|
||||
msgstr ""
|
||||
"Prijenos je trenutačno onemogućen, pokušaj kasnije ili kontaktiraj "
|
||||
"administratora (%1)."
|
||||
|
||||
#: themes/default/templates/index.html.ep:77 themes/default/templates/index.html.ep:79 themes/default/templates/myfiles.html.ep:116 themes/default/templates/partial/lutim.js.ep:72 themes/default/templates/partial/lutim.js.ep:76
|
||||
msgid "View link"
|
||||
msgstr "Pogledaj poveznicu"
|
||||
|
||||
#: themes/default/templates/about.html.ep:22
|
||||
msgid "What about the software which provides the service?"
|
||||
msgstr "Što je sa softverom koji pruža uslugu?"
|
||||
|
||||
#: themes/default/templates/about.html.ep:3
|
||||
msgid "What is Lutim?"
|
||||
msgstr "Što je Lutim?"
|
||||
|
||||
#: themes/default/templates/about.html.ep:15
|
||||
msgid "Who owns rights on images uploaded on Lutim?"
|
||||
msgstr "Tko posjeduje prava nad slikama postavljene na Lutimu?"
|
||||
|
||||
#: themes/default/templates/about.html.ep:12
|
||||
msgid "Yes, it is! On the other side, for legal reasons, your IP address will be stored when you send an image. Don't panic, it is normally the case of all sites on which you send files!"
|
||||
msgstr ""
|
||||
"Da, je! Međutim, iz pravnih razloga, tvoja IP adresa će se spremiti kada "
|
||||
"pošalješ sliku. Bez panike, to je normalno za sve stranice na koje šalješ "
|
||||
"datoteke!"
|
||||
|
||||
#: themes/default/templates/about.html.ep:10
|
||||
msgid "Yes, it is! On the other side, if you want to support the developer, you can do it via <a href=\"https://www.tipeee.com/fiat-tux\">Tipeee</a> or via <a href=\"https://liberapay.com/sky/\">Liberapay</a>."
|
||||
msgstr ""
|
||||
"Da, je! Međutim, ako želiš podržati programera, to možete učiniti putem "
|
||||
"usluge <a href=\"https://www.tipeee.com/fiat-tux\">Tipeee</a> ili <a href=\" "
|
||||
"https://liberapay.com/sky/\">Liberapay</a>."
|
||||
|
||||
#: themes/default/templates/zip.html.ep:6
|
||||
msgid "You asked to download a zip archive for too much files."
|
||||
msgstr "Zatražio/la si preuzimanje zip arhive za previše datoteka."
|
||||
|
||||
#: themes/default/templates/about.html.ep:8
|
||||
msgid "You can, optionally, request that the image(s) posted on Lutim to be deleted at first view (or download) or after the delay selected from those proposed."
|
||||
msgstr ""
|
||||
"Opcionalno možeš zatražiti da se objavljene slike na Lutimu izbrišu pri "
|
||||
"prvom pregledu (ili preuzimanju) ili nakon odabrane odgode od predloženih."
|
||||
|
||||
#: lib/Lutim/Controller/Authent.pm:27
|
||||
msgid "You have been successfully logged in."
|
||||
msgstr "Uspješno si prijavljan/a."
|
||||
|
||||
#: lib/Lutim/Controller/Authent.pm:66 themes/default/templates/logout.html.ep:3
|
||||
msgid "You have been successfully logged out."
|
||||
msgstr "Uspješno si odjevljen/a."
|
||||
|
||||
#: themes/default/templates/gallery.html.ep:31
|
||||
msgid "Zoom in/out"
|
||||
msgstr "Uvećaj/Umanji prikaz"
|
||||
|
||||
#: themes/default/templates/about.html.ep:27
|
||||
msgid "and on"
|
||||
msgstr "i na"
|
||||
|
||||
#: themes/default/templates/about.html.ep:40
|
||||
msgid "arabic translation"
|
||||
msgstr "prijevod na arapski"
|
||||
|
||||
#: themes/default/templates/about.html.ep:27
|
||||
msgid "core developer"
|
||||
msgstr "izvorni programer"
|
||||
|
||||
#: lib/Lutim.pm:340 lib/Lutim/Command/cron/stats.pm:154 lib/Lutim/Command/cron/stats.pm:168 lib/Lutim/Command/cron/stats.pm:185 themes/default/templates/index.html.ep:3 themes/default/templates/myfiles.html.ep:3 themes/default/templates/partial/raw.js.ep:21 themes/default/templates/partial/raw.js.ep:4 themes/default/templates/raw.html.ep:6
|
||||
msgid "no time limit"
|
||||
msgstr "bez vremenskog ograničenja"
|
||||
|
||||
#: themes/default/templates/about.html.ep:38
|
||||
msgid "occitan translation"
|
||||
msgstr "prijevod na okcitanski"
|
||||
|
||||
#: themes/default/templates/about.html.ep:27
|
||||
msgid "on"
|
||||
msgstr "na"
|
||||
|
||||
#: themes/default/templates/about.html.ep:39
|
||||
msgid "paste image to upload ability"
|
||||
msgstr "umetni sliku za mogućnost prijenosa"
|
||||
|
||||
#: themes/default/templates/about.html.ep:41
|
||||
msgid "russian translation"
|
||||
msgstr "prijevod na ruski"
|
||||
|
||||
#: themes/default/templates/about.html.ep:36
|
||||
msgid "spanish translation"
|
||||
msgstr "prijevod na španjolski"
|
||||
|
||||
#: themes/default/templates/about.html.ep:28
|
||||
msgid "webapp developer"
|
||||
msgstr "programer web-aplikacije"
|
||||
@@ -4,8 +4,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"PO-Revision-Date: 2020-10-11 23:59+0000\n"
|
||||
"Last-Translator: Валентин Бородко <valya.spaces@gmail.com>\n"
|
||||
"PO-Revision-Date: 2022-12-15 21:38+0000\n"
|
||||
"Last-Translator: Дмитрий Кузнецов <dk65536@gmail.com>\n"
|
||||
"Language-Team: Russian <https://weblate.framasoft.org/projects/lutim/"
|
||||
"default-theme/ru/>\n"
|
||||
"Language: ru\n"
|
||||
@@ -14,7 +14,7 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||
"X-Generator: Weblate 4.1\n"
|
||||
"X-Generator: Weblate 4.14.1\n"
|
||||
|
||||
#. (7)
|
||||
#. (30)
|
||||
@@ -182,9 +182,8 @@ msgstr ""
|
||||
"lutim\">главную страницу проекта</a>."
|
||||
|
||||
#: themes/default/templates/partial/navbar.html.ep:80
|
||||
#, fuzzy
|
||||
msgid "Fork me!"
|
||||
msgstr "Выложить меня!"
|
||||
msgstr "Форкни меня!"
|
||||
|
||||
#: themes/default/templates/index.html.ep:10 themes/default/templates/index.html.ep:13 themes/default/templates/myfiles.html.ep:60 themes/default/templates/myfiles.html.ep:63
|
||||
msgid "Gallery link"
|
||||
|
||||
@@ -147,7 +147,7 @@ function delImage(e) {
|
||||
url: '<%= url_for('/') %>d/'+short+'/'+token,
|
||||
method: 'GET',
|
||||
data: {
|
||||
format: 'json'
|
||||
_format: 'json'
|
||||
},
|
||||
success: function(data) {
|
||||
if (data.success) {
|
||||
|
||||
2
themes/korrigan/.gitignore
vendored
Normal file
2
themes/korrigan/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
public/packed/
|
||||
templates/data.html.ep
|
||||
35
themes/korrigan/Makefile
Normal file
35
themes/korrigan/Makefile
Normal file
@@ -0,0 +1,35 @@
|
||||
EN=lib/Lutim/I18N/en.po
|
||||
FR=lib/Lutim/I18N/fr.po
|
||||
DE=lib/Lutim/I18N/de.po
|
||||
ES=lib/Lutim/I18N/es.po
|
||||
OC=lib/Lutim/I18N/oc.po
|
||||
AR=lib/Lutim/I18N/ar.po
|
||||
SEDOPTS=-e "s@SOME DESCRIPTIVE TITLE@Lutim language file@" \
|
||||
-e "s@YEAR THE PACKAGE'S COPYRIGHT HOLDER@2015 Luc Didry@" \
|
||||
-e "s@CHARSET@utf8@" \
|
||||
-e "s@the PACKAGE package@the Lutim package@" \
|
||||
-e '/^\#\. (/{N;/\n\#\. (/{N;/\n.*\.\.\/default\//{s/\#\..*\n.*\#\./\#. (/g}}}' \
|
||||
-e '/^\#\. (/{N;/\n.*\.\.\/default\//{s/\n/ /}}'
|
||||
SEDOPTS2=-e '/^\#.*\.\.\/default\//,+3d'
|
||||
XGETTEXT=carton exec ../../local/bin/xgettext.pl
|
||||
CARTON=carton exec
|
||||
|
||||
locales:
|
||||
$(XGETTEXT) -D templates -D ../default/templates -o $(EN) 2>/dev/null
|
||||
$(XGETTEXT) -D templates -D ../default/templates -o $(FR) 2>/dev/null
|
||||
$(XGETTEXT) -D templates -D ../default/templates -o $(DE) 2>/dev/null
|
||||
$(XGETTEXT) -D templates -D ../default/templates -o $(ES) 2>/dev/null
|
||||
$(XGETTEXT) -D templates -D ../default/templates -o $(OC) 2>/dev/null
|
||||
$(XGETTEXT) -D templates -D ../default/templates -o $(AR) 2>/dev/null
|
||||
sed $(SEDOPTS) -i $(EN)
|
||||
sed $(SEDOPTS2) -i $(EN)
|
||||
sed $(SEDOPTS) -i $(FR)
|
||||
sed $(SEDOPTS2) -i $(FR)
|
||||
sed $(SEDOPTS) -i $(DE)
|
||||
sed $(SEDOPTS2) -i $(DE)
|
||||
sed $(SEDOPTS) -i $(ES)
|
||||
sed $(SEDOPTS2) -i $(ES)
|
||||
sed $(SEDOPTS) -i $(OC)
|
||||
sed $(SEDOPTS) -i $(OC)
|
||||
sed $(SEDOPTS2) -i $(AR)
|
||||
sed $(SEDOPTS2) -i $(AR)
|
||||
17
themes/korrigan/Readme.md
Normal file
17
themes/korrigan/Readme.md
Normal file
@@ -0,0 +1,17 @@
|
||||
I know there is a lot to work on but this fits my needs for now and don't have much time to rework the theme from beginning.
|
||||
|
||||
Feel free to open a merge request for improvements.
|
||||
|
||||

|
||||
|
||||
# Credits:
|
||||
|
||||
* Triskel image comes from https://upload.wikimedia.org/wikipedia/commons/0/07/Triskele-Symbol-spiral-five-thirds-turns.svg
|
||||
|
||||
# License:
|
||||
|
||||
[MIT](https://opensource.org/licenses/MIT)
|
||||
|
||||
# Author:
|
||||
|
||||
[nicofrand](https://nicofrand.eu) ([Twitter](https://twitter.com/@nicofrand), [Mastodon](https://mastodon.social/@nicofrand))
|
||||
22
themes/korrigan/lib/Lutim/I18N.pm
Normal file
22
themes/korrigan/lib/Lutim/I18N.pm
Normal file
@@ -0,0 +1,22 @@
|
||||
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
|
||||
package Lutim::I18N;
|
||||
|
||||
use base 'Locale::Maketext';
|
||||
use File::Basename qw/dirname/;
|
||||
use Locale::Maketext::Lexicon {
|
||||
_auto => 1,
|
||||
_decode => 1,
|
||||
_style => 'gettext',
|
||||
'*' => [
|
||||
Gettext => dirname(__FILE__) . '/I18N/*.po',
|
||||
Gettext => $app_dir . 'themes/default/lib/Lutim/I18N/*.po',
|
||||
]
|
||||
};
|
||||
|
||||
use vars qw($app_dir);
|
||||
BEGIN {
|
||||
use Cwd;
|
||||
my $app_dir = getcwd;
|
||||
}
|
||||
|
||||
1;
|
||||
BIN
themes/korrigan/preview.png
Normal file
BIN
themes/korrigan/preview.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 156 KiB |
178
themes/korrigan/public/css/korrigan.css
Normal file
178
themes/korrigan/public/css/korrigan.css
Normal file
@@ -0,0 +1,178 @@
|
||||
|
||||
/* Yeched'mad CSS */
|
||||
:root {
|
||||
--theme-blue: #0060DF;
|
||||
--theme-blue-hover: #45A1FF;
|
||||
}
|
||||
|
||||
body {
|
||||
position: relative;
|
||||
background-color: #EEEEEE;
|
||||
|
||||
background-size: cover;
|
||||
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
body::before,
|
||||
body::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
body::before {
|
||||
background-size: cover;
|
||||
background-image: url("../img/background.svg");
|
||||
}
|
||||
|
||||
body::after {
|
||||
background: linear-gradient(to bottom, rgba(255, 255, 255, 0.75) 4em, transparent 4em);
|
||||
}
|
||||
|
||||
body .navbar-default {
|
||||
background-color: transparent;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
body .navbar-default .open > a,
|
||||
body .navbar-default .open > a:focus,
|
||||
body .navbar-default .open > a:hover,
|
||||
body .navbar-default .open > a:active {
|
||||
background-color: rgba(11, 103, 183, 0.5);
|
||||
}
|
||||
|
||||
body > .container {
|
||||
flex-grow: 1;
|
||||
background-color: #FFFFFF;
|
||||
padding: 3em;
|
||||
border-radius: 5px;
|
||||
box-shadow: 1px 1px 5px #333333;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 1.15em;
|
||||
|
||||
/* SVG coming from https://upload.wikimedia.org/wikipedia/commons/0/07/Triskele-Symbol-spiral-five-thirds-turns.svg */
|
||||
background-image: url('../img/triskel.svg');
|
||||
background-size: 500px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: -125px calc(100% + 150px);
|
||||
}
|
||||
|
||||
body > .container .upload-info {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
body > .container::before,
|
||||
body > .container::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body.index > .container > * {
|
||||
background-color: rgba(255, 255, 255, 0.8);
|
||||
width: calc(50% - 2em);
|
||||
border-bottom-left-radius: inherit;
|
||||
border-bottom-right-radius: inherit;
|
||||
}
|
||||
|
||||
body .logo {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body .header {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
body .hennypenny {
|
||||
color: var(--theme-blue);
|
||||
margin-top: 0;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
body label {
|
||||
font-weight: normal;
|
||||
display: block;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
body input[type='checkbox'] {
|
||||
-moz-appearance: none;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
|
||||
position: static;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
vertical-align: middle;
|
||||
display: inline-flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
|
||||
background-color: #555555;
|
||||
width: 3rem;
|
||||
height: 1.5rem;
|
||||
margin-top: 0.25em;
|
||||
margin-bottom: 0.25em;
|
||||
border: none;
|
||||
border-radius: 1em;
|
||||
}
|
||||
|
||||
body input[type='checkbox']:checked {
|
||||
color: #FFFFFF;
|
||||
background-color: var(--theme-blue);
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
body input[type='checkbox']::after {
|
||||
content: '';
|
||||
margin: 0 0.15rem;
|
||||
width: 1.2rem;
|
||||
height: 1.2rem;
|
||||
border-radius: 50%;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
body .uploader-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
body .uploader {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
flex-grow: 1;
|
||||
border: 2px dashed #DDDDDD;
|
||||
border-radius: 5px;
|
||||
color: #6F7986;
|
||||
}
|
||||
|
||||
body .uploader:hover {
|
||||
background-color: #FDFEFF;
|
||||
}
|
||||
|
||||
body .uploader div.browser label {
|
||||
background-color: var(--theme-blue);
|
||||
}
|
||||
|
||||
body .uploader-container form .label {
|
||||
display: block;
|
||||
}
|
||||
|
||||
body .btn {
|
||||
background-color: var(--theme-blue);
|
||||
color: white;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
body .btn:hover,
|
||||
body .btn:focus,
|
||||
body .btn:active {
|
||||
background-color: var(--theme-blue-hover);
|
||||
}
|
||||
1
themes/korrigan/public/img/background.svg
Normal file
1
themes/korrigan/public/img/background.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 39 KiB |
63
themes/korrigan/public/img/triskel.svg
Normal file
63
themes/korrigan/public/img/triskel.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 12 KiB |
251
themes/korrigan/templates/index.html.ep
Normal file
251
themes/korrigan/templates/index.html.ep
Normal file
@@ -0,0 +1,251 @@
|
||||
% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:
|
||||
% my %d = (
|
||||
% delay_0 => l('no time limit'),
|
||||
% delay_1 => l('24 hours'),
|
||||
% delay_365 => l('1 year')
|
||||
% );
|
||||
|
||||
<div id="gallery-url" class="hidden row">
|
||||
<form class="form col-sm-12">
|
||||
<div class="form-group">
|
||||
<label for="gallery-url-input"><%= l('Gallery link') %></label>
|
||||
<div class="input-group">
|
||||
<a class="input-group-addon" id="gallery-url-link" href="#" target="_blank" title="<%= l('Gallery link') %>">
|
||||
<span class="icon icon-picture"></span>
|
||||
</a>
|
||||
<input class="form-control" name="gallery-url-input" type="text" id="gallery-url-input" readonly></input>
|
||||
<a href="#" class="input-group-addon jsonly copy-to-clipboard-link" title="<%= l('Copy to clipboard') %>">
|
||||
<span class="icon icon-clipboard"></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div id="zip-url" class="hidden row">
|
||||
<form class="form col-sm-12">
|
||||
<div class="form-group">
|
||||
<label for="zip-url-input"><%= l('Download zip link') %></label>
|
||||
<div class="input-group">
|
||||
<a class="input-group-addon" id="zip-url-link" href="#" target="_blank" title="<%= l('Download zip link') %>">
|
||||
<span class="icon icon-file-archive"></span>
|
||||
</a>
|
||||
<input class="form-control" name="zip-url-input" type="text" id="zip-url-input" readonly></input>
|
||||
<a href="#" class="input-group-addon jsonly copy-to-clipboard-link" title="<%= l('Copy to clipboard') %>">
|
||||
<span class="icon icon-clipboard"></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div id="random-url" class="hidden row">
|
||||
<form class="form col-sm-12">
|
||||
<div class="form-group">
|
||||
<label for="random-url-input"><%= l('Random image link') %></label>
|
||||
<div class="input-group">
|
||||
<a class="input-group-addon" id="random-url-link" href="#" target="_blank" title="<%= l('Random image link') %>">
|
||||
<span class="icon icon-shuffle"></span>
|
||||
</a>
|
||||
<input class="form-control" name="random-url-input" type="text" id="random-url-input" readonly></input>
|
||||
<a href="#" class="input-group-addon jsonly copy-to-clipboard-link" title="<%= l('Copy to clipboard') %>">
|
||||
<span class="icon icon-clipboard"></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="messages">
|
||||
% if (config('always_encrypt')) {
|
||||
<p><%= l('The images are encrypted on the server (Lutim does not keep the key).') %></p>
|
||||
% }
|
||||
% if (defined(stash('short'))) {
|
||||
% my $url = url_for('/'.stash('short'))->to_abs();
|
||||
<div class="alert alert-success">
|
||||
<div>
|
||||
% if (defined(stash('thumb'))) {
|
||||
<div class="preview">
|
||||
<a href="<%= $url.'.'.stash('ext') %>" target="_blank"><img class="thumbnail img-responsive" alt="<%= stash('filename') %> thumbnail" src="<%= stash('thumb') %>"></a>
|
||||
</div>
|
||||
% }
|
||||
<div>
|
||||
% # Display image informations
|
||||
<h4>
|
||||
<a href="<%= $url.'.'.stash('ext') %>" target="_blank"><%= stash('filename') %></a>
|
||||
<a title="<%= l('Tweet it!') %>" target="_blank" href="https://twitter.com/share?url=<%= $url %>?t"><span class="icon icon-twitter"></span></a>
|
||||
</h4>
|
||||
% my $delete_url = url_for('delete', {short => stash('real_short'), token => stash('token')})->to_abs();
|
||||
<form class="form">
|
||||
<div class="form-group">
|
||||
<label class="sr-only" for="view"><%= l('View link') %></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon"><a href="<%= $url.'.'.stash('ext') %>" target="_blank"><span class="icon icon-eye" title =" <%= l('View link') %>"></span></a></div>
|
||||
<input type="text" class="form-control" id="view" value="<%= $url.'.'.stash('ext') %>" readonly>
|
||||
<a href="#" class="input-group-addon jsonly copy-to-clipboard-link" title="<%= l('Copy to clipboard') %>"><span class="icon icon-clipboard"></span></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="sr-only" for="markdown"><%= l('Markdown syntax') %></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon"><span class="markdown-mark-solid" title ="<%= l('Markdown syntax') %>"></span></div>
|
||||
<input type="text" class="form-control" id="markdown" value="" readonly>
|
||||
<a href="#" class="input-group-addon jsonly copy-to-clipboard-link" title="<%= l('Copy to clipboard') %>"><span class="icon icon-clipboard"></span></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="sr-only" for="download"><%= l('Download link') %></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon"><a href="<%= $url %>?dl"><span class="icon icon-download" title ="<%= l('Download link') %>"></span></a></div>
|
||||
<input type="text" class="form-control" id="download" value="<%= $url %>?dl" readonly>
|
||||
<a href="#" class="input-group-addon jsonly copy-to-clipboard-link" title="<%= l('Copy to clipboard') %>"><span class="icon icon-clipboard"></span></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="sr-only" for="share"><%= l('Link for share on social networks') %></label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon"><a href="<%= $url %>?t" target="_blank"><span class="icon icon-share" title ="<%= l('Link for share on social networks') %>"></span></a></div>
|
||||
<input type="text" class="form-control" id="share" value="<%= $url %>?t" readonly>
|
||||
<a href="#" class="input-group-addon jsonly copy-to-clipboard-link" title="<%= l('Copy to clipboard') %>"><span class="icon icon-clipboard"></span></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<span class="form-control-static"><%= link_to $delete_url => ( class => "btn btn-default col-xs-12 text-left", title => l('Deletion link') ) => begin %><span class="icon icon-trash"></span> <%= $delete_url %> <%= end %></span>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
% # Delay modification form
|
||||
% my $modify_url = url_for('modify', {short => stash('real_short'), token => stash('token')})->to_abs();
|
||||
<form class="form col-sm-11 col-sm-offset-1" method="POST" action="<%== $modify_url %>">
|
||||
<div class="form-group form-inline">
|
||||
<input name="image_url" type="hidden" value="<%= $url %>">
|
||||
<select name="delete-day" class="form-control">
|
||||
%= include 'partial/for_my_delay', d => \%d
|
||||
</select>
|
||||
<div class="">
|
||||
<label>
|
||||
<input type="checkbox" name="first-view"> <%= l('Delete at first view?') %>
|
||||
</label>
|
||||
</div>
|
||||
<%= submit_button l('Let\'s go!'), class => 'btn btn-sm btn-default btn-primary', id => 'submitmodbutton' %>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
% }
|
||||
% if (defined(flash('success'))) {
|
||||
<div class="alert alert-success">
|
||||
<button type="button" class="close jsonly" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<p><%== flash('success') %></p>
|
||||
</div>
|
||||
% }
|
||||
% if (defined(flash('msg'))) {
|
||||
<div class="alert alert-danger">
|
||||
<button type="button" class="close jsonly" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<strong><%= l('Something bad happened') %></strong><br>
|
||||
<%= flash('filename') %> <%= flash('msg') %>
|
||||
</div>
|
||||
% }
|
||||
</div>
|
||||
|
||||
<noscript>
|
||||
<form class="form" method="POST" action="<%= url_for('/') %>" enctype="multipart/form-data">
|
||||
<div class="form-group form-inline">
|
||||
<select name="delete-day" class="form-control">
|
||||
%= include 'partial/for_my_delay', d => \%d
|
||||
</select>
|
||||
<div class="">
|
||||
<label>
|
||||
<input type="checkbox" name="first-view"> <%= l('Delete at first view?') %>
|
||||
</label>
|
||||
<label <%== (config('always_encrypt')) ? 'class="always-encrypt"' : '' %>>
|
||||
<input type="checkbox" name="crypt"> <%= l('Encrypt the image (Lutim does not keep the key).') %>
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" name="keep-exif"> <%= l('Keep EXIF tags') %>
|
||||
</label>
|
||||
</div>
|
||||
% if ($c->config('watermark_path') && $c->config('watermark_enforce') eq 'none') {
|
||||
<select name="watermark" class="form-control">
|
||||
<option value="tiling" <%== is_wm_selected('tiling') %>>
|
||||
<%= l('Tiling watermark') %>
|
||||
</option>
|
||||
<option value="single" <%== is_wm_selected('single') %>>
|
||||
<%= l('Single watermark') %>
|
||||
</option>
|
||||
<option value="none" <%== is_wm_selected('none') %>>
|
||||
<%= l('No watermark') %>
|
||||
</option>
|
||||
</select>
|
||||
% }
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="lutim-file"><%= l('Send an image') %></label>
|
||||
<input type="file" name="file" id="lutim-file" accept="image/*">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="lutim-file-url"><%= l('Upload an image with its URL') %></label>
|
||||
<input type="url" name="lutim-file-url" placeholder="<%= l('Image URL') %>">
|
||||
</div>
|
||||
<p class="help-block"><%= l('Only images are allowed') %></p>
|
||||
<%= submit_button l('Let\'s go!'), class => 'btn btn-default btn-primary', id => 'submitbutton' %>
|
||||
</form>
|
||||
</noscript>
|
||||
|
||||
<!-- D&D Zone-->
|
||||
<div class="jsonly">
|
||||
<select id="delete-day" class="form-control">
|
||||
%= include 'partial/for_my_delay', d => \%d
|
||||
</select>
|
||||
<div class="">
|
||||
<label>
|
||||
<input type="checkbox" id="first-view"> <%= l('Delete at first view?') %>
|
||||
</label>
|
||||
<label <%== (config('always_encrypt')) ? 'class="always-encrypt"' : '' %>>
|
||||
<input type="checkbox" id="crypt"> <%= l('Encrypt the image (Lutim does not keep the key).') %>
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" id="keep-exif"> <%= l('Keep EXIF tags') %>
|
||||
</label>
|
||||
</div>
|
||||
% if ($c->config('watermark_path') && $c->config('watermark_enforce') eq 'none') {
|
||||
<select id="watermark" class="form-control">
|
||||
<option value="tiling" <%== is_wm_selected('tiling') %>>
|
||||
<%= l('Tiling watermark') %>
|
||||
</option>
|
||||
<option value="single" <%== is_wm_selected('single') %>>
|
||||
<%= l('Single watermark') %>
|
||||
</option>
|
||||
<option value="none" <%== is_wm_selected('none') %>>
|
||||
<%= l('No watermark') %>
|
||||
</option>
|
||||
</select>
|
||||
% }
|
||||
</div>
|
||||
</div><!-- Warning: beings in default.html.ep -->
|
||||
|
||||
<div class="jsonly uploader-container">
|
||||
<div id="drag-and-drop-zone" class="uploader">
|
||||
<div><%= l('Drag & drop images here') %></div>
|
||||
<div class="or"><%= l('-or-') %></div>
|
||||
<div class="browser">
|
||||
<label class="btn">
|
||||
<span><%= l('Click to open the file browser') %></span>
|
||||
<input type="file" name="files[]" multiple="multiple" title='<%= l('Click to open the file browser') %>' accept="image/*">
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<p class="help-block"><%= l('Only images are allowed') %></p>
|
||||
<form class="form-horizontal" method="POST" action="<%== url_for('add') %>">
|
||||
<p>
|
||||
<span class="hidden-spin spin"> <span class="icon-spinner animate-spin pull-right"></span></span>
|
||||
<label for="lutim-file-url"><%= l('Upload an image with its URL') %></label>
|
||||
|
||||
<input type="url" name="lutim-file-url" class="form-control" id="lutim-file-url" placeholder="<%= l('Image URL') %>">
|
||||
</p>
|
||||
<a href="#" class="btn pull-right" id="file-url-button"><%= l('Let\'s go!') %></a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /D&D Zone -->
|
||||
98
themes/korrigan/templates/layouts/default.html.ep
Normal file
98
themes/korrigan/templates/layouts/default.html.ep
Normal file
@@ -0,0 +1,98 @@
|
||||
% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:
|
||||
% use Mojo::Util qw(url_escape);
|
||||
% my $twitter_url = 'https://twitter.com/share';
|
||||
% my $url = url_for('/')->to_abs();
|
||||
% $twitter_url .= '?url='.url_escape("$url")
|
||||
% .'&text=Check out this %23Lutim instance! ';
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Lutim</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta charset="utf-8" />
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<link rel="icon" type="image/png" href="<%= url_for('/img/favicon.png') %>">
|
||||
<link rel="icon" sizes="128x128" href="<%= url_for('/img/lutim128.png') %>">
|
||||
<link rel="icon" sizes="196x196" href="<%= url_for('/img/lutim196.png') %>">
|
||||
<link rel="apple-touch-icon" href="<%= url_for('/img/lutim60.png') %>">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="<%= url_for('/img/lutim76.png') %>">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="<%= url_for('/img/lutim120.png') %>">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="<%= url_for('/img/lutim152.png') %>">
|
||||
<link rel="apple-touch-icon-precomposed" sizes="128x128" href="<%= url_for('/img/lutim128.png') %>">
|
||||
%= stylesheet '/css/common.min.css'
|
||||
% if (current_route 'stats') {
|
||||
%= stylesheet '/css/morris-0.5.1.min.css'
|
||||
% } else {
|
||||
%= stylesheet '/css/not_stats.min.css'
|
||||
% }
|
||||
% if (current_route 'gallery') {
|
||||
%= stylesheet '/css/gallery.min.css'
|
||||
% }
|
||||
%= stylesheet '/css/korrigan.css'
|
||||
</head>
|
||||
<body class="<%== current_route %>">
|
||||
%= include 'partial/navbar', twitter_url => $twitter_url
|
||||
<div class="container">
|
||||
<div class="upload-info"><!-- Warning: ends in index.html.ep -->
|
||||
<div>
|
||||
% if (defined(config('hosted_by'))) {
|
||||
<div class="pull-right">
|
||||
<%== config('hosted_by') %>
|
||||
</div>
|
||||
% }
|
||||
<div class="header">
|
||||
<div class="pull-left hidden-xs logo">
|
||||
<img src="<%= url_for('/img/Lutim_small.png') %>" alt="Lutim logo" width="57" height="75">
|
||||
</div>
|
||||
<a class="link_nocol" href="<%= url_for('/') %>" title="<%= l('Homepage') %>"><h1 class="hennypenny">Let's Upload That Image!</h1></a>
|
||||
</div>
|
||||
</div>
|
||||
% if (defined(config('broadcast_message'))) {
|
||||
<div class="alert alert-info">
|
||||
<strong><%== config('broadcast_message') %></strong>
|
||||
</div>
|
||||
% }
|
||||
% if (defined(stash('stop_upload'))) {
|
||||
<div class="alert alert-danger">
|
||||
<strong><%= stash('stop_upload') %></strong>
|
||||
</div>
|
||||
% }
|
||||
<%= content %>
|
||||
</div>
|
||||
% if (defined(config('piwik_img'))) {
|
||||
<img src="<%== config('piwik_img') %>" class="border-zero" alt="">
|
||||
% }
|
||||
%= javascript '/js/jquery-3.2.1.min.js'
|
||||
%= javascript '/partial/manifest.js'
|
||||
%= javascript '/js/toastify.js'
|
||||
%= javascript '/js/bootstrap.min.js'
|
||||
%= javascript '/partial/common.js'
|
||||
% if (current_route 'stats') {
|
||||
%= javascript '/js/lutim.js'
|
||||
%= javascript '/js/raphael-min.js'
|
||||
%= javascript '/js/morris-0.5.1.min.js'
|
||||
%= javascript '/js/stats.js'
|
||||
%= javascript '/partial/raw.js'
|
||||
% } elsif (!(current_route 'about')) {
|
||||
%= javascript '/js/lutim.js'
|
||||
%= javascript '/js/dmuploader.min.js'
|
||||
% }
|
||||
% if (current_route 'index') {
|
||||
%= javascript '/partial/lutim.js'
|
||||
% }
|
||||
% if (current_route 'gallery') {
|
||||
%= javascript '/js/photoswipe.min.js'
|
||||
%= javascript '/js/photoswipe-ui-default.min.js'
|
||||
%= javascript '/js/jszip.min.js'
|
||||
%= javascript '/js/FileSaver.min.js'
|
||||
%= javascript '/partial/gallery.js'
|
||||
%= javascript '/partial/lutim.js'
|
||||
% }
|
||||
% if (current_route 'myfiles') {
|
||||
%= javascript '/js/moment-with-locales.min.js'
|
||||
%= javascript '/partial/myfiles.js'
|
||||
% }
|
||||
</body>
|
||||
</html>
|
||||
494
themes/korrigan/templates/partial/lutim.js.ep
Normal file
494
themes/korrigan/templates/partial/lutim.js.ep
Normal file
@@ -0,0 +1,494 @@
|
||||
% # vim:set sw=4 ts=4 sts=4 ft=javascript expandtab:
|
||||
function selectInput() {
|
||||
$(this).select();
|
||||
}
|
||||
function cleanName(name, empty) {
|
||||
if (typeof(name) === 'undefined') {
|
||||
return name;
|
||||
}
|
||||
if (empty !== undefined && empty !== null && empty) {
|
||||
return name.replace(/&(l|g)t;/g, '').replace(/"/g, '\'');
|
||||
} else {
|
||||
return name.replace(/</g, '<').replace(/>/g, '>');
|
||||
}
|
||||
}
|
||||
function tw_url(url) {
|
||||
return btn = [
|
||||
'<a title="<%= l('Tweet it!') %>" target="_blank" href="https://twitter.com/share?url=<%== url_for('/')->to_abs() %>', url, '?t" class="btn btn-default">',
|
||||
'<span class="icon icon-twitter"></span>',
|
||||
'</a>'
|
||||
].join('');
|
||||
}
|
||||
function modifyImage(e) {
|
||||
e.preventDefault();
|
||||
var url = $(this).data('modlink');
|
||||
var short = $(this).data('modshort');
|
||||
modify(url, short);
|
||||
}
|
||||
function modify(url, short) {
|
||||
var limit = $('#day-'+short).val();
|
||||
var del_at_view = ($('#first-view-'+short).prop('checked')) ? 1 : 0;
|
||||
$.ajax({
|
||||
url : url,
|
||||
type : 'POST',
|
||||
data : {
|
||||
'image_url' : '<%== url_for('/')->to_abs() %>'+short,
|
||||
'format' : 'json',
|
||||
'delete-day' : limit,
|
||||
'first-view' : del_at_view
|
||||
},
|
||||
success: function(data) {
|
||||
updateItem(short, limit, del_at_view);
|
||||
goodToast(data.msg);
|
||||
},
|
||||
error: function() {
|
||||
badToast('<%= l('Error while trying to modify the image.') %>');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function buildMessage(success, msg) {
|
||||
if(success) {
|
||||
var s_url = link([msg.short, '.', msg.ext].join(''), '');
|
||||
var thumb = (msg.thumb !== null) ? [
|
||||
'<div class="preview">',
|
||||
'<a href="', s_url, '" target="_blank">',
|
||||
'<img class="thumbnail img-responsive" alt="', cleanName(msg.filename, true), ' thumbnail" src="', msg.thumb, '">',
|
||||
'</a>',
|
||||
'</div>'
|
||||
].join('') : ''
|
||||
return [
|
||||
'<div class="alert alert-success" id="alert-', msg.real_short, '">',
|
||||
'<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>',
|
||||
'<div>', thumb,
|
||||
'<div>',
|
||||
'<h4>',
|
||||
'<a href="', s_url, '" target="_blank">',
|
||||
msg.filename,
|
||||
'</a>',
|
||||
'</h4>',
|
||||
'<form class="form">',
|
||||
'<div class="form-group">',
|
||||
'<label class="sr-only" for="view', msg.real_short, '"><%= l('View link') %></label>',
|
||||
'<div class="input-group input-group-sm">',
|
||||
'<div class="input-group-btn adjust-addon">',
|
||||
'<a href="', s_url, '" target="_blank" class="btn btn-default">',
|
||||
'<span class="icon icon-eye" title=" <%= l('View link') %>"></span>',
|
||||
'</a>',
|
||||
'</div>',
|
||||
'<input type="text" class="form-control view-link-input" id="view', msg.real_short, '" value="', s_url, '" readonly>',
|
||||
'<a href="#" class="input-group-addon copy-to-clipboard-link" title="<%= l('Copy to clipboard') %>">',
|
||||
'<span class="icon icon-clipboard"></span>',
|
||||
'</a>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'<div class="form-group">',
|
||||
'<label class="sr-only" for="markdown', msg.real_short, '"><%= l('Markdown syntax') %></label>',
|
||||
'<div class="input-group input-group-sm">',
|
||||
'<div class="input-group-addon adjust-addon">',
|
||||
'<span class="markdown-mark-solid" title="<%= l('Markdown syntax') %>"></span>',
|
||||
'</div>',
|
||||
'<input type="text" class="form-control" id="markdown', msg.real_short, '" value=", ')" readonly>',
|
||||
'<a href="#" class="input-group-addon copy-to-clipboard-link" title="<%= l('Copy to clipboard') %>">',
|
||||
'<span class="icon icon-clipboard"></span>',
|
||||
'</a>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'<div class="form-group">',
|
||||
'<label class="sr-only" for="download', msg.real_short, '"><%= l('Download link') %></label>',
|
||||
'<div class="input-group input-group-sm">',
|
||||
'<div class="input-group-btn adjust-addon">',
|
||||
'<a href="', link(msg.short, 'dl'), '" class="btn btn-default">',
|
||||
'<span class="icon icon-download" title="<%= l('Download link') %>"></span>',
|
||||
'</a>',
|
||||
'</div>',
|
||||
'<input type="text" class="form-control" id="download', msg.real_short, '" value="', link(msg.short, 'dl'), '" readonly>',
|
||||
'<a href="#" class="input-group-addon copy-to-clipboard-link" title="<%= l('Copy to clipboard') %>">',
|
||||
'<span class="icon icon-clipboard"></span>',
|
||||
'</a>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'<div class="form-group">',
|
||||
'<label class="sr-only" for="share', msg.real_short, '"><%= l('Link for share on social networks') %></label>',
|
||||
'<div class="input-group input-group-sm">',
|
||||
'<div class="input-group-btn adjust-addon">',
|
||||
'<a href="', link(msg.short, 't'), '" target="_blank" class="btn btn-default">',
|
||||
'<span class="icon icon-share" title="<%= l('Link for share on social networks') %>"></span>',
|
||||
'</a>',
|
||||
tw_url(msg.short),
|
||||
'</div>',
|
||||
'<input type="text" class="form-control" id="share', msg.real_short, '" value="', link(msg.short, 't'), '" readonly>',
|
||||
'<a href="#" class="input-group-addon copy-to-clipboard-link" title="<%= l('Copy to clipboard') %>">',
|
||||
'<span class="icon icon-clipboard"></span>',
|
||||
'</a>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'<div class="form-group">',
|
||||
'<div class="input-group">',
|
||||
'<span class="form-control-static">', link(msg.real_short, '', msg.token), '</span>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'</form>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'<div class="row">',
|
||||
'<form class="form col-sm-11 col-sm-offset-1" role="form" method="POST" action="', link(msg.real_short, '', msg.token, true), '">',
|
||||
'<div class="form-group form-inline">',
|
||||
'<select id="day-', msg.real_short, '" name="delete-day" class="form-control">',
|
||||
% my @delays = split(',', $self->config('proposed_delays'));
|
||||
% for my $delay (@delays) {
|
||||
% my $text = (defined($d->{'delay_'.$delay})) ? $d->{'delay_'.$delay} : l('%1 days', $delay);
|
||||
% if (config('max_delay')) {
|
||||
% if ($delay) {
|
||||
% if ($delay < config('max_delay')) {
|
||||
'<option value="<%= $delay %>" <%== is_selected($delay) %>><%= $text %></option>',
|
||||
% } elsif ($delay == config('max_delay')) {
|
||||
'<option value="<%= $delay %>" <%== is_selected($delay) %>><%= $text %></option>',
|
||||
% last;
|
||||
% } else {
|
||||
% my $text = ($delay == 1) ? l('24 hours') : l('%1 days', $delay);
|
||||
'<option value="<%= config('max_delay') %>" <%== is_selected(config('max_delay')) %>><%= l('%1 days', config('max_delay')) %></option>',
|
||||
% last;
|
||||
% }
|
||||
% }
|
||||
% } else {
|
||||
'<option value="<%= $delay %>" <%== is_selected($delay) %>><%= $text %></option>',
|
||||
% }
|
||||
% }
|
||||
'</select> ',
|
||||
'<div class="checkbox">',
|
||||
'<label>',
|
||||
'<input id="first-view-', msg.real_short, '" type="checkbox" name="first-view"> <%= l('Delete at first view?') %>',
|
||||
'</label>',
|
||||
'</div> ',
|
||||
'<a href="#" class="btn btn-sm btn-default btn-primary modify-image" data-modlink="', link(msg.real_short, '', msg.token, true),'" data-modshort="', msg.real_short,'">',
|
||||
'<%= l('Let\'s go!') %>',
|
||||
'</a>',
|
||||
'</div>',
|
||||
'</form>',
|
||||
'</div>',
|
||||
'</div>'
|
||||
].join('');
|
||||
} else {
|
||||
return [
|
||||
'<div class="alert alert-danger">',
|
||||
'<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>',
|
||||
'<strong><%= l('Something bad happened') %></strong><br>',
|
||||
cleanName(msg.filename, false),
|
||||
'<br>',
|
||||
cleanName(msg.msg, false),
|
||||
'</div>'
|
||||
].join('');
|
||||
}
|
||||
}
|
||||
function bindddz(firstview, deleteday) {
|
||||
$('#drag-and-drop-zone').dmUploader({
|
||||
url: '<%== url_for('/') %>',
|
||||
dataType: 'json',
|
||||
allowedTypes: 'image/*',
|
||||
maxFileSize: <%= config('max_file_size') %>,
|
||||
onNewFile: function(id, file){
|
||||
$('.messages').append([
|
||||
'<div id="', id, '-div">',
|
||||
cleanName(file.name), '<br>',
|
||||
'<div class="progress">',
|
||||
'<div id="', id, '"class="progress-bar progress-striped active width-zero" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">',
|
||||
'<span id="', id, '-text" class="pull-left pdg-left-10"> 0%</span>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'</div>'
|
||||
].join(''));
|
||||
},
|
||||
onUploadProgress: function(id, percent){
|
||||
var percentStr = ' '+percent+'%';
|
||||
$('#'+id).prop('aria-valuenow', percent);
|
||||
$('#'+id).css('width', percent+'%');
|
||||
$('#'+id+'-text').html(percentStr);
|
||||
},
|
||||
onUploadSuccess: function(id, data){
|
||||
data.msg.filename = cleanName(data.msg.filename);
|
||||
$('#'+id+'-div').remove();
|
||||
if ($('#copy-all').length === 0 && data.success) {
|
||||
$('.messages').prepend([
|
||||
'<div class="col-xs-12 col-sm-11 col-sm-offset-1">',
|
||||
'<a id="copy-all" href="#" class="btn btn-info copy-all-to-clipboard-link">',
|
||||
'<%= l('Copy all view links to clipboard') %>',
|
||||
'</a>',
|
||||
'</div>'
|
||||
].join(''));
|
||||
}
|
||||
$('.messages').append(buildMessage(data.success, data.msg));
|
||||
$('#del-'+data.msg.real_short).on('click', function(e) {
|
||||
e.preventDefault();
|
||||
rmFromShortHash(data.msg.short+'.'+data.msg.ext)
|
||||
rmFromZipHash(data.msg.short);
|
||||
rmFromRandomHash(data.msg.short);
|
||||
});
|
||||
$('#del-'+data.msg.real_short).on('click', delImage);
|
||||
if (data.success) {
|
||||
addToShortHash(data.msg.short+'.'+data.msg.ext);
|
||||
addToZipHash(data.msg.short);
|
||||
addToRandomHash(data.msg.short);
|
||||
$('.close').unbind('click', evaluateCopyAll);
|
||||
$('.close').on('click', evaluateCopyAll);
|
||||
$('input[type=\'text\']').unbind("click", selectInput);
|
||||
$('input[type=\'text\']').on("click", selectInput);
|
||||
$('.copy-all-to-clipboard-link').unbind('click', copyAllToClipboard);
|
||||
$('.copy-all-to-clipboard-link').on('click', copyAllToClipboard);
|
||||
$('.modify-image').unbind('click', modifyImage);
|
||||
$('.modify-image').on('click', modifyImage);
|
||||
$('.copy-to-clipboard-link').unbind('click', clickOnCopyLink);
|
||||
$('.copy-to-clipboard-link').on('click', clickOnCopyLink);
|
||||
addItem(data.msg);
|
||||
}
|
||||
},
|
||||
onUploadError: function(id, message){
|
||||
$('.messages').append(buildMessage(false, ''));
|
||||
},
|
||||
onFileSizeError: function(file){
|
||||
$('.messages').append(buildMessage(false, { filename: file.name, msg: '<%= l('The file exceed the size limit (%1)', config('max_file_size')) %>'}));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function upload_url(e) {
|
||||
e.preventDefault();
|
||||
var val = $('#lutim-file-url').val();
|
||||
if (val !== undefined && val !== '') {
|
||||
$('#lutim-file-url').prop('disabled', 'disabled');
|
||||
$('.hidden-spin').css('display', 'block');
|
||||
$.ajax({
|
||||
url : '<%== url_for('/') %>',
|
||||
type : 'POST',
|
||||
data : {
|
||||
'lutim-file-url' : val,
|
||||
'format' : 'json',
|
||||
'first-view' : ($('#first-view').prop('checked')) ? 1 : 0,
|
||||
'crypt' : ($('#crypt').prop('checked')) ? 1 : 0,
|
||||
'delete-day' : $('#delete-day').val()
|
||||
},
|
||||
success: function(data) {
|
||||
data.msg.filename = cleanName(data.msg.filename);
|
||||
$('.messages').append(buildMessage(data.success, data.msg));
|
||||
if (data.success) {
|
||||
if ($('#copy-all').length === 0) {
|
||||
$('.messages').prepend([
|
||||
'<div class="col-xs-12 col-sm-11 col-sm-offset-1">',
|
||||
'<a id="copy-all" href="#" class="btn btn-info copy-all-to-clipboard-link">',
|
||||
'<%= l('Copy all view links to clipboard') %>',
|
||||
'</a>',
|
||||
'</div>'
|
||||
].join(''));
|
||||
}
|
||||
$('#lutim-file-url').val('');
|
||||
addToShortHash(data.msg.short+'.'+data.msg.ext);
|
||||
addToZipHash(data.msg.short);
|
||||
addToRandomHash(data.msg.short);
|
||||
$('#del-'+data.msg.real_short).on('click', delImage);
|
||||
$('.close').unbind('click', evaluateCopyAll);
|
||||
$('.close').on('click', evaluateCopyAll);
|
||||
addItem(data.msg);
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
$('.messages').append(buildMessage(false, ''));
|
||||
},
|
||||
complete: function() {
|
||||
$('#lutim-file-url').prop('disabled', '');
|
||||
$('.hidden-spin').css('display', 'none');
|
||||
$('.copy-all-to-clipboard-link').unbind('click', copyAllToClipboard);
|
||||
$('.copy-all-to-clipboard-link').on('click', copyAllToClipboard);
|
||||
$('.modify-image').unbind('click', modifyImage);
|
||||
$('.modify-image').on('click', modifyImage);
|
||||
$('.copy-to-clipboard-link').unbind('click', clickOnCopyLink);
|
||||
$('.copy-to-clipboard-link').on('click', clickOnCopyLink);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function fileUpload(file) {
|
||||
var fd = new FormData();
|
||||
fd.append('file', file);
|
||||
|
||||
fd.append('format', 'json');
|
||||
fd.append('first-view', ($('#first-view').prop('checked')) ? 1 : 0);
|
||||
fd.append('crypt', ($('#crypt').prop('checked')) ? 1 : 0);
|
||||
fd.append('delete-day', ($('#delete-day').val()));
|
||||
|
||||
$('.messages').append([
|
||||
'<div id="1-div">', cleanName(file.name), '<br>',
|
||||
'<div class="progress">',
|
||||
'<div id="1" class="progress-bar progress-striped active width-zero" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">',
|
||||
'<span id="1-text" class="pull-left pdg-left-10"> 0%</span>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'</div>'
|
||||
].join(''));
|
||||
// Ajax Submit
|
||||
$.ajax({
|
||||
url: '<%== url_for('/') %>',
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
data: fd,
|
||||
cache: false,
|
||||
contentType: false,
|
||||
processData: false,
|
||||
forceSync: false,
|
||||
xhr: function(){
|
||||
var xhrobj = $.ajaxSettings.xhr();
|
||||
if(xhrobj.upload){
|
||||
xhrobj.upload.addEventListener('progress', function(event) {
|
||||
var percent = 0;
|
||||
var position = event.loaded || event.position;
|
||||
var total = event.total || e.totalSize;
|
||||
if(event.lengthComputable){
|
||||
percent = Math.ceil(position / total * 100);
|
||||
}
|
||||
|
||||
var percentStr = ' '+percent+'%';
|
||||
$('#1').prop('aria-valuenow', percent);
|
||||
$('#1').css('width', percent+'%');
|
||||
$('#1-text').html(percentStr);
|
||||
}, false);
|
||||
}
|
||||
|
||||
return xhrobj;
|
||||
},
|
||||
success: function (data, message, xhr){
|
||||
$('#1-div').remove();
|
||||
if ($('#copy-all').length === 0 && data.success) {
|
||||
$('.messages').prepend([
|
||||
'<div class="col-xs-12 col-sm-11 col-sm-offset-1">',
|
||||
'<a id="copy-all" href="#" class="btn btn-info copy-all-to-clipboard-link">',
|
||||
'<%= l('Copy all view links to clipboard') %>',
|
||||
'</a>',
|
||||
'</div>'
|
||||
].join(''));
|
||||
}
|
||||
data.msg.filename = cleanName(data.msg.filename);
|
||||
$('.messages').append(buildMessage(data.success, data.msg));
|
||||
if (data.success) {
|
||||
$('.close').unbind('click', evaluateCopyAll);
|
||||
$('.close').on('click', evaluateCopyAll);
|
||||
addItem(data.msg);
|
||||
}
|
||||
},
|
||||
error: function (xhr, status, errMsg){
|
||||
$('.messages').append(buildMessage(false, ''));
|
||||
},
|
||||
complete: function () {
|
||||
$('.copy-all-to-clipboard-link').unbind('click', copyAllToClipboard);
|
||||
$('.copy-all-to-clipboard-link').on('click', copyAllToClipboard);
|
||||
$('.modify-image').unbind('click', modifyImage);
|
||||
$('.modify-image').on('click', modifyImage);
|
||||
$('.copy-to-clipboard-link').unbind('click', clickOnCopyLink);
|
||||
$('.copy-to-clipboard-link').on('click', clickOnCopyLink);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function initPaste() {
|
||||
/*
|
||||
actually FF and Chrome doesn't handle paste events the same way...
|
||||
for ff we need to create a editable div and register an event to it.
|
||||
When user paste, the image is "really" pasted in the div. Then, we need to iterate throught
|
||||
the div childs to get images. Previsouly FF didn't have the paste event so it was esay to figure on wich browser we were.
|
||||
But firefox now have a paste event so I test it...
|
||||
|
||||
on Chrome the file object is directlyt in the clipboard.
|
||||
*/
|
||||
var b = 'FF';
|
||||
try {
|
||||
//FF
|
||||
var cbe = new ClipboardEvent('hop');
|
||||
} catch(hop) {
|
||||
//under webkkit Clipboard doesn't have arguments...
|
||||
b = 'WK'
|
||||
}
|
||||
if (b === 'FF') {
|
||||
var pasteDiv = document.createElement('div');
|
||||
pasteDiv.addEventListener('paste', onPasteFF);
|
||||
pasteDiv.setAttribute('class', 'pasteZone');
|
||||
pasteDiv.setAttribute('contenteditable', true);
|
||||
|
||||
document.getElementsByTagName('body')[0].appendChild(pasteDiv);
|
||||
pasteDiv.focus();
|
||||
|
||||
document.addEventListener('click', function(event) {
|
||||
var t = $(event.target);
|
||||
|
||||
switch (t[0].nodeName.toUpperCase()) {
|
||||
case 'A':
|
||||
case 'BUTTON':
|
||||
case 'INPUT':
|
||||
case 'SELECT':
|
||||
case 'SPAN':
|
||||
case 'LABEL':
|
||||
break;
|
||||
default:
|
||||
if (t[0].parentNode.nodeName.toUpperCase() !== 'SELECT') {
|
||||
pasteDiv.focus();
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
document.addEventListener('paste', onPaste);
|
||||
}
|
||||
}
|
||||
|
||||
function waitforpastedata(elem, savedcontent) {
|
||||
if (elem.childNodes && elem.childNodes.length > 0) {
|
||||
processpaste(elem, savedcontent);
|
||||
} else {
|
||||
var that = {
|
||||
e: elem,
|
||||
s: savedcontent
|
||||
};
|
||||
that.callself = function () {
|
||||
waitforpastedata(that.e, that.s);
|
||||
}
|
||||
setTimeout(that.callself, 20);
|
||||
}
|
||||
}
|
||||
|
||||
function processpaste(elem, savedcontent) {
|
||||
var pasteZone = document.getElementsByClassName('pasteZone')[0];
|
||||
var f = new Image();
|
||||
|
||||
f.onload = function(){
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.width = f.width;
|
||||
canvas.height = f.height;
|
||||
|
||||
var ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(f, 0, 0, canvas.width, canvas.height);
|
||||
|
||||
canvas.toBlob(function(blob) {
|
||||
var url = window.URL.createObjectURL(blob);
|
||||
fileUpload(blob);
|
||||
});
|
||||
}
|
||||
|
||||
f.src = pasteZone.childNodes[0].src;
|
||||
|
||||
pasteZone.innerHTML = '';
|
||||
}
|
||||
|
||||
function onPasteFF(e) {
|
||||
var pasteZone = document.getElementsByClassName('pasteZone')[0];
|
||||
waitforpastedata(pasteZone, 'savedcontent');
|
||||
}
|
||||
|
||||
function onPaste(e) {
|
||||
var items = e.clipboardData.items;
|
||||
for(var i = 0; i < items.length; i++) {
|
||||
var item = items[i];
|
||||
if (/image/.test(item.type)) {
|
||||
var file = item.getAsFile();
|
||||
fileUpload(file);
|
||||
} else {
|
||||
//not image..
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user