311 Commits
0.4 ... 0.11.3

Author SHA1 Message Date
Luc Didry
b8d2defe61 Fix gallery bug 2018-07-31 13:23:56 +02:00
Luc Didry
c030e371ae Fix stats graph if no upload happens in the time range 2018-07-31 12:55:15 +02:00
Luc Didry
85d0aabef8 Add upload_enabled info to server infos endpoint 2018-07-30 13:45:48 +02:00
Luc Didry
da8a0642ec Fix year_disabled_in_month_pct stat 2018-07-30 13:36:24 +02:00
Luc Didry
9696da7c01 Bump version (0.11) 2018-07-29 22:19:43 +02:00
Luc Didry
4585b7af8f [i18n] Update translations 2018-07-29 22:18:40 +02:00
Luc Didry
3feeeac39d Merge branch 'development' into 'master'
Time for a new release

Closes #82, #61, #84, #67, #70, #5, #76, #79, #56, #77, #78, #48, #80, #83 et #81

See merge request luc/lutim!51
2018-07-29 22:06:42 +02:00
Luc Didry
f7b81e701f Remove Bitcoin support 2018-07-29 22:01:50 +02:00
Luc Didry
8c7a2a75a1 [i18n] Update translations 2018-07-29 21:59:02 +02:00
Luc Didry
e1533a8804 Add /about/image forgotten endpoint 2018-07-29 21:33:41 +02:00
Luc Didry
f8b28525f6 Merge branch 'fix-82' into 'development'
Fix #82 - Add optional authentication

See merge request luc/lutim!50
2018-07-29 20:19:43 +02:00
Luc Didry
182f4ccf4e Fix #82 - Add optional authentication 2018-07-29 20:15:01 +02:00
Quentin
07344aa0c9 Update oc.po 2018-07-29 18:49:19 +02:00
Quentin
b8d74beea3 Update oc.po 2018-07-29 18:48:48 +02:00
Luc Didry
985a781a5f Merge branch 'fix-61' into 'development'
Fix #61 - Add modal to modify expiration delay from "myfiles" page

See merge request luc/lutim!49
2018-07-29 17:48:15 +02:00
Luc Didry
ee936c1f79 Fix #61 - Add modal to modify expiration delay from "myfiles" page 2018-07-29 17:43:32 +02:00
Luc Didry
9ea2234f7d [i18n] Update translations 2018-07-29 15:58:11 +02:00
Luc Didry
7c199a5c87 Fix gallery/zip/random link generator on myfiles page 2018-07-29 15:48:50 +02:00
Luc Didry
4d5fed4d02 Merge branch 'fix-84' into 'development'
Fix #84 - Add link to generate random file in collection

See merge request luc/lutim!48
2018-07-29 15:48:49 +02:00
Luc Didry
b088db9c5e [i18n] Update translations 2018-07-29 15:48:49 +02:00
Luc Didry
ea358d4a4c Fix #84 - Add link to generate random file in collection 2018-07-29 15:48:49 +02:00
Luc Didry
47b38daad5 Merge branch 'fix-67' into 'development'
Fix #67 - Add localStorage export and import feature

See merge request luc/lutim!47
2018-07-29 15:48:49 +02:00
Luc Didry
46dcb0256f Add fix #70 item in CHANGELOG 2018-07-29 15:48:49 +02:00
Luc Didry
8fe738adc4 Fix #67 - Add localStorage export and import feature 2018-07-29 15:48:49 +02:00
Luc Didry
9b90119061 Merge branch 'fix-5' into 'development'
Fix #5 - Allow to use a fixed domain

See merge request luc/lutim!46
2018-07-29 15:48:49 +02:00
Luc Didry
78bb3f37c7 Merge branch 'fix-70' into 'development'
Fix #70 - Fix stats files generation with non-default theme

See merge request luc/lutim!45
2018-07-29 15:48:48 +02:00
Luc Didry
f2f785e6d4 Fix #5 - Allow to use a fixed domain 2018-07-29 15:48:48 +02:00
Luc Didry
15e587464d Merge branch 'fix-76' into 'development'
Fix #76 Add .zip file check in the tests

See merge request luc/lutim!44
2018-07-29 15:48:48 +02:00
Luc Didry
4ef5e67f4b Fix #70 - Fix stats files generation with non-default theme 2018-07-29 15:48:48 +02:00
Luc Didry
ef090954c3 Merge branch 'fix-79' into 'development'
Fix #79 Add CLI command

See merge request luc/lutim!43
2018-07-29 15:48:48 +02:00
Luc Didry
b42bf08363 Fix #76 Add .zip file check in the tests
This commit is dedicated to Nartagnan, who is supporting me with Ğ1.
Many thanks :-)
2018-07-29 15:48:48 +02:00
Luc Didry
b5ea181bea Improve image CLI command
- Add CLI command to remove images
- Add CLI command to search images based on the uploader's IP address

This commit is dedicated to Schoumi, who is supporting me on Tipeee.
Many thanks :-)
2018-07-29 15:48:48 +02:00
Luc Didry
b84420e6dc [i18n] Update oc translation 2018-07-29 15:48:47 +02:00
Luc Didry
701a78ac94 Add CLI command to print informations about images
This commit is dedicated to JCB, who is supporting me with Ğ1.
Many thanks :-)
2018-07-29 15:48:47 +02:00
Luc Didry
0d1ca8aa98 [i18n] Use ISO::639_1
This commit is dedicated to Schoumi, who is supporting me on Tipeee.
Many thanks :-)
2018-07-29 15:48:47 +02:00
Luc Didry
fbe3c3bc13 [zanata] update Makefile to push or pull only on master and dev branch 2018-07-29 15:48:47 +02:00
Luc Didry
a7f2fd051d [i18n] update locales 2018-07-29 15:48:47 +02:00
Luc Didry
c18e6c84af [zanata] update CI 2018-07-29 15:48:47 +02:00
Luc Didry
10eafcfdc3 Merge branch 'fix-56' into 'development'
Fix #56 Add a message saying how many images there is in the gallery

See merge request luc/lutim!42
2018-07-29 15:48:47 +02:00
Luc Didry
033ff3c54f [zanata] update CI 2018-07-29 15:48:46 +02:00
Luc Didry
9645c8a2f3 Fix #56 Add a message saying how many images there is in the gallery 2018-07-29 15:48:46 +02:00
Luc Didry
4193f03d7a Remove @framasky as default tweet_card_via setting 2018-07-29 15:48:46 +02:00
Luc Didry
8a92ef9567 Merge branch 'fix-77' into 'development'
Fix #77 Add X-Content-Type-Options, X-XSS-Protection, X-Frame-Options headers

See merge request luc/lutim!41
2018-07-29 15:48:46 +02:00
Luc Didry
ed47431415 Merge branch 'fix-78' into 'development'
Fix #78 Add CSP Header

See merge request luc/lutim!40
2018-07-29 15:48:46 +02:00
Luc Didry
247cb41cc5 Fix #77 Add X-Content-Type-Options, X-XSS-Protection, X-Frame-Options headers 2018-07-29 15:48:46 +02:00
Luc Didry
acf0ec75e7 [i18n] Update translations 2018-07-29 15:48:45 +02:00
Luc Didry
83a8fbeeeb Fix #78 Add CSP Header
+ update morris and raphael graph libraries
+ some changes in "myfiles" table
2018-07-29 15:48:45 +02:00
Luc Didry
707e434d2c [zanata] Fix Makefile for CI 2018-07-29 15:48:45 +02:00
Luc Didry
8a412a33c3 Update Changelog 2018-07-29 15:48:45 +02:00
Luc Didry
3eb8db123e Fix #48 No more scroll to top on click + add notifications to actions 2018-07-29 15:48:45 +02:00
Luc Didry
dd9dc7bd7d Fix #80 Gzip static assets with Mojolicious::Plugin::GzipStatic 2018-07-29 15:48:45 +02:00
Luc Didry
c91d46bc68 Fix #83 Use Mojolicious::Plugin::Chi + Add memcached ability 2018-07-29 15:48:45 +02:00
Luc Didry
8dd2ab87f9 Add code coverage in CI 2018-07-29 15:48:44 +02:00
Luc Didry
b3ec85daf3 Better .gitlab-ci.yml
- change order
- use postgresql service
- install only needed deps

This commit is dedicated to Schoumi, who is supporting me on Tipeee.
Many thanks :-)
2018-07-29 15:48:44 +02:00
Luc Didry
dc2b17c7af Fix #81 Allow to install only needed deps
This commit is dedicated to Agnès Maillard, who is supporting me with Ğ1.
Many thanks :-)
2018-07-29 15:48:44 +02:00
Luc Didry
4c53669caa [zanata] Use new Zanata URL 2018-07-29 15:47:58 +02:00
Luc Didry
b5e73e09bf Change internationalization link 2018-07-19 17:05:20 +02:00
Luc Didry
e62cb50ab1 Fix bug in cache system 2018-05-07 18:27:07 +02:00
Luc Didry
cf9504bb30 Fix another bug on zip file creation (missing IV on decryption) 2018-04-26 21:10:02 +02:00
Luc Didry
36a007d2f7 Bump version (0.10.2) 2018-04-24 18:39:28 +02:00
Luc Didry
f013359314 Fix Zip files creation 2018-04-24 18:37:51 +02:00
Luc Didry
1fda560056 Fix #73 bug on theme creation 2018-04-15 13:39:33 +02:00
Luc Didry
adc2d00552 Merge branch 'development' 2018-04-07 12:19:41 +02:00
Luc Didry
95f4c372e3 Bump version 2018-04-07 12:18:43 +02:00
Luc Didry
4f39a86b0a Add partial index on SQLite 2018-04-07 12:11:27 +02:00
Luc Didry
09f1492486 Create merge conflict on zanata.xml 2018-04-07 12:07:43 +02:00
Luc Didry
163a1e2a66 Disable images' counter option 2018-04-07 11:53:51 +02:00
Luc Didry
f26e7ba5ff Add option to disable logs 2018-04-07 11:44:34 +02:00
Luc Didry
7d29e3d3dd [i18n] Correctly handle regionalized languages 2018-04-03 12:03:35 +02:00
Luc Didry
a7bb73b158 Merge branch 'development' into 'development'
suite de luc/lutim!26

See merge request luc/lutim!33
2018-03-19 10:42:47 +01:00
brunob
dc371daf15 suite de luc/lutim!26
ref #63 ; my bad...
2018-03-19 10:36:39 +01:00
Luc Didry
bb097294e2 Built-in image cache system 2018-03-17 15:55:34 +01:00
Luc Didry
cfab86c4b4 Move some tasks to recurring instead of being in after_dispatch hook 2018-03-17 10:30:09 +01:00
Luc Didry
fb562dd9b8 [postgresql] Add partial index to speed up some queries 2018-03-17 10:24:47 +01:00
Luc Didry
0e63bf766e Merge remote-tracking branch 'origin/master' into development 2018-03-12 10:09:01 +01:00
Luc Didry
8ab966f83c Update translations 2018-03-12 10:05:24 +01:00
Luc Didry
86b3652471 Bump version 2018-03-11 23:07:22 +01:00
Luc Didry
c29acb8944 Update translations 2018-03-11 23:06:55 +01:00
Alexander Sapozhnikov
564a0ef69d Russian translation added 2018-03-11 23:06:50 +01:00
Luc Didry
781d1bc721 Update translations 2018-03-11 22:44:08 +01:00
Luc Didry
7cf9f8b6ec Merge branch 'shoorick/lutim-master' into development 2018-03-11 21:44:51 +01:00
Alexander Sapozhnikov
1405b078c0 Russian translation added 2018-03-12 00:58:34 +05:00
Luc Didry
95db024ab8 Merge remote-tracking branch 'origin/master' into development 2018-03-11 14:34:27 +01:00
Luc Didry
fe07945af7 Replace Twitter account URL with Mastodon one 2018-03-11 14:30:35 +01:00
Luc Didry
a59b728aa6 Merge remote-tracking branch 'origin/master' into development 2018-03-11 10:29:15 +01:00
Luc Didry
f27cf293dd Create a conflict on zanata.xml between master and dev branches 2018-03-11 10:26:54 +01:00
Luc Didry
85c025f2c3 Zanata.xml -> development branch 2018-03-11 10:25:28 +01:00
Luc Didry
0295ba3666 Use woff2 format for HennyPenny font 2018-03-11 10:14:10 +01:00
Luc Didry
485436aa67 Bump version 2018-03-09 23:45:21 +01:00
Luc Didry
0e0e6da677 Fix langage drop-down 2018-03-09 23:44:12 +01:00
Luc Didry
781e96c073 Allow to use HTML in broadcast message 2018-03-09 23:43:10 +01:00
Luc Didry
fb610e1a80 Remove old targets from Makefile 2018-03-09 23:42:40 +01:00
Luc Didry
13b7ece5e2 Add db_path default value 2018-03-09 23:19:28 +01:00
Luc Didry
7446edba48 Bump version 2018-03-09 20:03:32 +01:00
Luc Didry
35eb60a27f Remove now unused Lutim::DB::SQLite 2018-03-09 20:03:07 +01:00
Luc Didry
0b1f21be31 Fix push-trad-to-zanata.sh perms 2018-03-09 19:57:33 +01:00
Luc Didry
b1e1e88af4 Merge branch 'development' into 'master'
Add script to push po files to zanata

See merge request luc/lutim!31
2018-03-09 19:54:33 +01:00
Luc Didry
68d3ddb61a Add script to push po files to zanata 2018-03-09 19:52:19 +01:00
Luc Didry
b6ac7d2818 Set zanata.xml to master version 2018-03-09 19:51:33 +01:00
Luc Didry
da36aad520 Merge branch 'development' into 'master'
Development

Closes #64, #68, #66 et #63

See merge request luc/lutim!30
2018-03-09 19:47:37 +01:00
Luc Didry
d00f151a2e Merge branch 'fix-64' into 'development'
Fix #64

See merge request luc/lutim!29
2018-03-09 19:43:16 +01:00
Luc Didry
9c79c9a392 Merge branch 'fix-68' into 'development'
Fix #68

See merge request luc/lutim!28
2018-03-09 19:39:01 +01:00
Luc Didry
eb575519ed Fix #64 2018-03-09 19:36:55 +01:00
Luc Didry
125bda1687 Fix #68 2018-03-09 19:33:07 +01:00
Luc Didry
b5836d88bb Merge branch 'fix-66' into 'development'
Fix #66

See merge request luc/lutim!27
2018-03-09 19:27:19 +01:00
Luc Didry
8daef83846 Fix #66
This commit is dedicated to Squeeek, who is supporting me with Ǧ1.
Many thanks :-)
2018-03-09 18:52:00 +01:00
Luc Didry
883004b7b6 Use random Initialization Vector for encryption
+ now use Mojo::SQLite instead of ORLite

This commit is dedicated to Antonio Ferreira, who is supporting me with Ǧ1.
Many thanks :-)
2018-03-09 16:53:38 +01:00
Luc Didry
5a5e629e29 Rename this informations in these details 2018-03-03 18:35:50 +01:00
Luc Didry
6daabaf054 Zanata integration 2018-03-03 18:12:40 +01:00
brunob
f94d72f978 précision pour le format de la valeur de conf proposed_delays 2018-03-03 18:02:35 +01:00
brunob
41abd109b6 Fix #63 : ajout d'une option de conf pour personnaliser les délais proposés
Pas certain que les modifications dans lib/ soient nécessaires, dans le doute, je les envoie.
2018-03-03 18:02:35 +01:00
Luc Didry
91d2be631b Regenerate locales with -u option + fr update 2018-03-03 18:02:35 +01:00
Luc Didry
56b87bb7c7 Fix ar.po (strings were deleted in previous merge) 2018-03-03 18:02:35 +01:00
Butterflyoffire Butterflyoffire
ab48e8976f Update ar.po. Left 9 strings to translate. 2018-03-03 18:02:35 +01:00
Luc Didry
fa5c3e465b Change bitcoin address 2018-03-03 18:02:35 +01:00
Luc Didry
474680e600 Rename template.pot to lutim.pot 2018-03-03 18:02:35 +01:00
Luc Didry
b19a3f6005 Delete Mojolicious::Plugin::AssetPack from cpanfile 2018-03-03 18:02:35 +01:00
Quentin
8e7065e714 Update oc.po 2018-03-03 18:02:35 +01:00
Luc Didry
2529234df9 template.pot generation 2018-03-03 18:02:35 +01:00
Luc Didry
5ad1caea68 Make gallery generation really sequential 2018-03-03 18:02:35 +01:00
Luc Didry
ef1297be7d Use Photoswipe for the gallery instead of Unite gallery 2018-03-03 18:02:35 +01:00
Luc Didry
d6b59c45a6 Fix Lutim::Plugin::Helpers needed in Mounter.pm 2018-03-03 18:02:35 +01:00
Luc Didry
59000d53d6 Add language changing dropdown 2018-03-03 18:02:35 +01:00
Luc Didry
4e1d36ce60 Small default UI change 2018-03-03 18:02:35 +01:00
Luc Didry
bcb0710fde Fix render_not_found crash (from a Mojolicious update) 2018-03-03 18:02:35 +01:00
Luc Didry
799124a58d Use Mojolicious::Plugin::StaticCache instead of AssetPack 2018-03-03 18:02:35 +01:00
Luc Didry
c9a6fd2be4 Change for a non-fluid layout 2018-03-03 18:02:35 +01:00
Luc Didry
9958a9cca9 Include arabic translation in Makefile, theme command + update AUTHORS 2018-03-03 18:02:35 +01:00
Butterflyoffire Butterflyoffire
6b012b7382 Adding i18n arabic. 2018-03-03 18:02:35 +01:00
Luc Didry
6921496a19 Update Changelog 2018-02-07 22:12:46 +01:00
Luc Didry
6ab6b76c8f Fix #65 2018-02-07 22:11:37 +01:00
Luc Didry
8b9791b6b4 Update AUTHORS.md 2018-01-15 09:14:26 +01:00
Luc Didry
6f43566664 Fix bug if dbtype not configured in lutim.conf
This commit is dedicated to Liandri, who is supporting me with great bzh food.
Many thanks :-)
2017-12-22 19:17:57 +01:00
Luc Didry
e7e02931ac Fix bug resulting in no EXIF tags deletion 2017-11-18 17:37:41 +01:00
Luc Didry
210a2a8df2 Update CHANGELOG for 0.8.5 2017-07-09 13:44:32 +02:00
Luc Didry
41e5f292eb Fix hennypenny.css for asset pack 2017-07-09 13:40:19 +02:00
Luc Didry
72f0469674 Udpate Changelog - release 0.8.4 2017-06-24 17:46:04 +02:00
Luc Didry
a842311304 Mitigate a bug using the same empty record twice
On the official instance, which is heavily used, some empty records are
used twice since the migration to PostgreSQL. Trying to choose randomly
among the available empty records to fix that and immediatly make them
not empty (add a fake path).

+ force lowest version of Net::SSLeay used, since the latest (more or
less) version is needed on Debian Stretch.
2017-06-24 17:43:29 +02:00
Luc Didry
ce84d403df Fix donut stats call 2017-06-15 10:29:25 +02:00
Luc Didry
ec6b9ce028 Update cpanfile: enforce Mojolicious::Plugin::AssetPack version 2017-06-14 12:00:35 +02:00
Luc Didry
321b8bbf97 Update CHANGELOG - 0.8.1 2017-06-13 23:08:08 +02:00
Luc Didry
78ce5dc69d Fix CI oblivion 2017-06-13 22:42:27 +02:00
Luc Didry
82289ece59 Fix #46 Server error if trying to zip an unexisting file 2017-06-13 22:10:59 +02:00
Luc Didry
32ca358886 Release 0.8 2017-06-13 20:08:02 +02:00
Luc Didry
c5dac2d5e9 Merge branch 'development' into 'master'
Merge development

Closes #40, #14, #27, #33, #39, and #9

See merge request !19
2017-06-13 19:57:50 +02:00
Luc Didry
88b77f91fb Fix CI 2017-06-12 21:41:03 +02:00
Quentin
75b645e6d4 Update oc.po 2017-06-12 19:38:40 +02:00
Quentin
9cfb694779 Update oc.po 2017-06-12 18:40:37 +02:00
Luc Didry
37b6f82f32 Add lutim-minion@.service 2017-06-11 20:45:44 +02:00
Luc Didry
65403d934c Update CI configuration
This commit is dedicated to Schoumi, who is supporting me on Tipeee.
Many thanks :-)
2017-06-11 19:58:07 +02:00
Luc Didry
36bae6e042 Add Minion support
This commit is dedicated to Brigitte, the queen of elves, who is supporting me.
Many thanks :-)
2017-06-11 19:56:59 +02:00
Luc Didry
2a0f2ef4a2 Improve cache (and so, load speed)
- Add Cache-control headers for static files
- Put almost all js/css stuff outside template
2017-06-11 11:25:34 +02:00
Luc Didry
54374765e7 Update .gitignore 2017-06-08 23:15:32 +02:00
Luc Didry
0cb82fee0b Update .gitlab-ci.yml (add test-pg and podcheck) 2017-06-08 23:13:46 +02:00
Luc Didry
b7e799353f Add stats in JSON format 2017-06-08 21:27:51 +02:00
Luc Didry
c5831168af Fix #40 2017-06-08 01:15:23 +02:00
Luc Didry
8a8e331de9 Merge branch 'issue-14-mr-5' into 'development'
Fix #14 and !5 Allow to paste images to upload them

See merge request !17
2017-06-07 23:47:52 +02:00
Luc Didry
790da8deeb Fix #14 and !5 Allow to paste images to upload them
This wouldn't have been possible without the great work of Alexis
Clairet (MR !5). I had to close the MR and report his work because of
the many changes in Lutim since he worked on it.

This commit is dedicated to Schoumi, who is supporting me on Tipeee.
Many thanks :-)
2017-06-07 23:43:14 +02:00
Luc Didry
c7b15dc952 Small changes for my git pre-commit hook 2017-06-07 22:52:33 +02:00
Luc Didry
4f8a27a10b Update Changelog 2017-06-07 22:50:29 +02:00
Luc Didry
6014ea4889 Fix bug: the localStorage wasn't modified if image's delay was modified
This commit is dedicated to Brigitte, the queen of elves, who is supporting me.
Many thanks :-)
2017-06-07 22:47:41 +02:00
Luc Didry
e389869414 Fix bug in image's delay modification 2017-06-07 22:00:10 +02:00
Luc Didry
c9dda1c720 Update Changelog 2017-06-07 20:56:06 +02:00
Luc Didry
3b1a6af092 Merge branch 'issue-27' into 'development'
Fix #27 Handle too much images in zip download URL

See merge request !16
2017-06-05 17:59:45 +02:00
Luc Didry
b7d4ea0a23 Fix #27 Handle too much images in zip download URL
This commit is dedicated to Schoumi, who is supporting me on Tipeee.
Many thanks :-)
2017-06-05 17:58:18 +02:00
Luc Didry
05dcdc2729 Merge branch 'issue-33' into 'development'
Fix #33 Add gallery constructor in "my files" list

See merge request !15
2017-06-05 11:55:06 +02:00
Luc Didry
b8212e4920 Fix #33 Add gallery constructor in "my files" list
This commit is dedicated to guilhemB, who is supporting me on Tipeee.
Many thanks :-)
2017-06-05 11:53:45 +02:00
Luc Didry
3faee2402c Update CHANGELOG 2017-06-05 11:10:23 +02:00
Luc Didry
ef1463f8c9 Merge branch 'issue-39' into 'development'
Issue 39

See merge request !14
2017-06-05 11:05:29 +02:00
Luc Didry
028961113c Fix #39 2017-06-05 11:04:20 +02:00
Luc Didry
63a7ad74cd Fix markdown font pb 2017-06-05 10:30:05 +02:00
Luc Didry
3f21ddb35a Merge branch 'issue-42' into 'development'
Issue 42

See merge request !13
2017-06-05 10:02:15 +02:00
Luc Didry
a8d38f6ea8 Fix bug 2017-06-05 10:01:28 +02:00
Luc Didry
efb71654d6 Update CHANGELOG 2017-06-05 09:58:38 +02:00
Luc Didry
8421efc3da Fix #9 Add functional tests
This commit is dedicated to Schoumi, who is supporting me on Tipeee.
Many thanks :-)
2017-06-04 17:38:00 +02:00
Luc Didry
e0f8ddec64 Add functional tests
This commit is dedicated to Brigitte, the queen of elves, who is supporting me.
Many thanks :-)
2017-06-04 11:05:31 +02:00
Luc Didry
1f03678348 Extract i18n strings from directories, not files 2017-06-04 11:00:52 +02:00
Luc Didry
9aed9a0f03 Fix typos and oblivions 2017-06-03 22:22:08 +02:00
Luc Didry
c2110dc171 [Not tested] Add Pg support
This commit is dedicated to Schoumi, who is supporting me on Tipeee.
Many thanks :-)
2017-06-02 19:18:10 +02:00
Luc Didry
381f4e934e Putting helpers in separate file
This commit is dedicated to guilhemB, who is supporting me on Tipeee.
Many thanks :-)
2017-06-02 18:21:03 +02:00
Luc Didry
b710c3250b Add missing vim modeline
This commit is dedicated to Schoumi, who is supporting me on Tipeee.
Many thanks :-)
2017-06-02 18:20:39 +02:00
Luc Didry
6738c49730 Add Liberapay and Tipeee buttons to support the author 2017-05-27 20:43:51 +02:00
Luc Didry
9318058f2b Update Changelog 2017-05-27 20:14:39 +02:00
Luc Didry
d2cd4b8335 Merge branch 'issue-42' into 'development'
Issue 42

See merge request !12
2017-05-27 15:57:20 +02:00
Luc Didry
b6d7860472 Update modules + ask at least Mojolicious 7.31
This commit is dedicated to guilhemB, who is supporting me on Tipeee.
Many thanks :-)
2017-05-27 15:53:51 +02:00
Luc Didry
9a4a5a5799 Issue #42; abstraction layer finished
This commit is dedicated to Schoumi, who is supporting me on Tipeee.
Many thanks :-)
2017-05-27 15:53:51 +02:00
Luc Didry
1a8d2ea171 Fix namespace change oblivion
This commit is dedicated to guilhemB, who is supporting me on Tipeee.
Many thanks :-)
2017-05-27 15:53:51 +02:00
Luc Didry
179def2d3e Work on #42: cleanbdd command
This commit is dedicated to Schoumi, who is supporting me on Tipeee.
Many thanks :-)
2017-05-27 15:53:51 +02:00
Luc Didry
0de43b74db First work on #42
- Start creating a DB abstraction layer
- Use this abstraction layer in watch and cleanfiles commands

This commit is dedicated to guilhemB, who is supporting me on Tipeee.
Many thanks :-)
2017-05-27 15:53:51 +02:00
Luc Didry
5dffc402c9 Merge branch 'deprec_fix' into 'master'
Fix #45

Closes #45

See merge request !11
2017-05-27 12:33:42 +02:00
Roberto Benfatto
b6cfec60e2 Fix #45 2017-05-27 12:20:26 +02:00
Luc Didry
efec636f2e Merge branch 'patch-2' into 'master'
Update oc.po

See merge request !9
2017-05-20 09:36:52 +02:00
Quentin
eb6dc4235a Update oc.po 2017-05-05 20:08:15 +02:00
Luc Didry
d1b6c00a55 Improve stats pages translation 2017-05-04 12:59:40 +02:00
Luc Didry
7af0ee5df4 Merge branch 'improve-stats-page' into 'master'
Improve statistics page

See merge request !8
2017-05-04 12:52:36 +02:00
Luc Didry
1b9dad0f3f Improve statistics page 2017-05-04 12:48:01 +02:00
Luc Didry
4c0df8f8b1 Force download if image is SVG 2017-02-13 21:35:44 +01:00
Luc Didry
4629d2ae2d Fix #37 2017-01-05 08:39:30 +01:00
Luc Didry
f4f25aab4f Add GET /infos API endpoint
See https://framagit.org/luc/lutim/wikis/API for details

This commit is dedicated to Schoumi. Thx for your support on Tipeee :-)
2016-11-14 13:13:07 +01:00
Luc Didry
c6ee5408da Merge branch 'housekeeping' into 'master'
General housekeeping

Correct various typos.
Change GitLab URL to framagit.org.

See merge request !6
2016-09-26 09:20:50 +02:00
Luc Didry
6cc48bb991 Merge branch 'patch-1' into 'master'
Update oc.po

Suites recommandations au sujet de l'occitan "général".

See merge request !7
2016-09-26 09:18:52 +02:00
Quentin
91174081b5 Update oc.po
Suites recommandations au sujet de l'occitan "général".
2016-09-25 19:12:59 +02:00
Luc Didry
a69e0df68d Add occitan translation, thanks to Quentin Pagès 2016-09-16 23:17:25 +02:00
Armando Lüscher
545059cbe5 Correct various typos.
Change GitLab URL to framagit.org.
2016-09-13 10:43:26 +02:00
Luc Didry
a848d7aef8 Add tmp/ to .gitignore 2016-07-19 14:27:09 +02:00
Luc Didry
cc3281fe2f Adapt stats task to theme system 2016-07-19 14:26:07 +02:00
Luc Didry
48cc398efb Small UI changes
+ updated bootstrap
+ add .gitignore when creating themes
+ moving bootstrap and fontello config.json into utilities folder
2016-07-19 13:23:59 +02:00
Luc Didry
4d2721f533 Fix Copy fallback instruction 2016-07-19 08:58:06 +02:00
Luc Didry
2923180f0c Add links to Tipeee and Liberapay 2016-07-18 21:41:10 +02:00
Luc Didry
4130a77aa0 Add theme system
Thanks to e-Jim to support me on Tipeee :-)
2016-07-18 21:27:53 +02:00
Luc Didry
dd4ca47ac0 Update cpanfile (fix #25) 2016-06-25 12:37:36 +02:00
Luc Didry
b63eebbefa Update Morris.js URL 2016-06-22 08:59:37 +02:00
Luc Didry
e767f850bf update CHANGELOG 2016-06-21 23:26:53 +02:00
Luc Didry
374b99f77d Add CSS::Minifier::XS dependency
It seems that it was not automatically installed as a dependency of
Mojolicious::Plugin::AssetPack :-(
2016-06-21 23:26:40 +02:00
Luc Didry
c58edbae83 Add "download zip" URL + better copy to clipboard method 2016-06-21 23:03:54 +02:00
Luc Didry
c03082c2c1 Do not try to remove EXIF tags from xcf or webp images 2016-06-09 23:37:43 +02:00
Luc Didry
9f872a3f6a Fix gallery URL not updated when closing image alert block 2016-06-09 23:36:54 +02:00
Luc Didry
fd3d9a6e31 Do not try to create thumbnails of webp images 2016-06-09 22:47:05 +02:00
Luc Didry
fbcc133e47 Do not thumbnail xcf files (gimp) 2016-06-08 21:51:26 +02:00
Luc Didry
e8eb804d3c Add files extension to gallery URL
This allows to have extensions in the zip package.

Plus do not add to the gallery URL if file is an xcf (gimp) in order to
prevent zip generation fail.
2016-06-08 21:47:44 +02:00
Luc Didry
453bc5d2c5 Fix #22 2016-06-08 18:14:36 +02:00
Luc Didry
c450b27c0d Change lightbox overlay color 2016-06-06 22:51:10 +02:00
Luc Didry
1bd82463d1 Fix typo in french translation 2016-06-06 22:39:04 +02:00
Luc Didry
6a4b0910d4 Fix typo in conf template 2016-06-06 22:28:32 +02:00
Luc Didry
ef6509a3bc Fix #20 2016-06-06 22:26:37 +02:00
Luc Didry
0a318dc4d4 Avoid having "gallery" as shortened URL 2016-06-06 22:09:39 +02:00
Luc Didry
58901989dd Only use the first frame of a gif to create the thumbnail
With a great number of frames, ImageMagick crashes.
2016-06-06 22:07:50 +02:00
Luc Didry
08a07cd93d Update dependencies 2016-06-06 22:07:31 +02:00
Luc Didry
a7884e8785 Fix gallery URL on image block closing 2016-06-06 22:00:22 +02:00
Luc Didry
41fef61f7c Fix SVG upload, broken when working on EXIF tags 2016-06-06 21:58:27 +02:00
Luc Didry
a1ce8618de Fix #16 2016-06-06 21:29:43 +02:00
Luc Didry
b60a849752 Fix #19 2016-06-06 21:23:41 +02:00
Luc Didry
b33c7d3d23 Update translation files 2016-06-06 21:16:27 +02:00
Luc Didry
99e5ea8c75 Changing all links from git.framasoft.org to framagit.org 2016-06-06 21:11:30 +02:00
Luc Didry
dced03c964 Update CHANGELOG 2016-06-06 21:11:08 +02:00
Luc Didry
fe06675d0b Add gallery. Fix #15 2016-06-06 21:07:12 +02:00
Luc Didry
1082f42682 Allow to set the encryption length in lutim.conf 2015-10-08 11:35:11 +02:00
Luc Didry
1dff747b64 Update Changelog 2015-10-08 11:26:58 +02:00
Luc Didry
c33840f3aa Use cryptographically secure random generator 2015-10-08 11:25:03 +02:00
Luc Didry
a9669b5f7b Add german translation (thx Thor77) 2015-10-04 15:44:53 +02:00
Luc Didry
86ee5287bf Fixes #11 Select input text when focus 2015-09-24 01:26:05 +02:00
Luc Didry
e51e8f3d3a Add CONTRIBUTING file 2015-09-24 01:07:13 +02:00
Luc Didry
688f4517c1 Rename Changes file 2015-09-24 01:06:15 +02:00
Luc Didry
1cb5aab686 Remove Item from localStorage when deleted (button or expired) 2015-09-24 01:03:30 +02:00
Luc Didry
0c23c9ba67 Fixe mistake on deletion link in myfiles page 2015-09-23 08:21:11 +02:00
Luc Didry
204df6bf08 Small UI change (make alert blocks more compact) 2015-09-21 22:15:33 +02:00
Luc Didry
2f96407f5c Add view links to thumbnails and filenames 2015-09-21 21:18:32 +02:00
Luc Didry
14943906d3 Add links before the input fields 2015-09-19 16:14:20 +02:00
Luc Didry
1aa6e9b859 Update Changes 2015-09-18 00:14:40 +02:00
Luc Didry
a64808f206 Fixes #3 - Add list of of user's images in localstorage 2015-09-18 00:12:15 +02:00
Luc Didry
af9323365c Move javascript which don't need templating to static js file 2015-09-17 21:47:37 +02:00
Luc Didry
7a7eb8f4cc Make copy-all button disappear if there is no more links 2015-09-17 21:37:10 +02:00
Luc Didry
170546df64 Update translations 2015-09-17 12:04:43 +02:00
Luc Didry
1ad1929a0e Add file extension to view link 2015-09-17 00:52:28 +02:00
Luc Didry
8b76684fcd Add Copy to clipboard buttons (each link + all links) 2015-09-17 00:18:42 +02:00
Luc Didry
71576ce749 Update twitter bootstrap 2015-09-11 00:28:19 +02:00
Luc Didry
e0b05ff0d1 Update Changes file 2015-09-10 01:27:05 +02:00
Luc Didry
f121a9f807 Remove infos in README since they are in the wiki
https://git.framasoft.org/luc/lutim/wikis/home
2015-09-10 01:14:24 +02:00
Luc Didry
d98f95811f Lower case Kharec's last name 2015-09-10 00:50:51 +02:00
Luc Didry
7472650b59 Put authors in a separate file 2015-09-10 00:50:01 +02:00
Luc Didry
a1fc2997c7 Update dependencies 2015-09-09 23:09:44 +02:00
Luc Didry
bb9fae43e2 Improve init files
Hypnotoad does not use "user" and "group" settings anymore. So I
removed the setting in the configuration template and changed some
things in the init files accordingly.

+ some fixes for annoying behavior in initV and systemd files
2015-09-09 23:07:13 +02:00
Luc Didry
bb5c7050bb Fixes #6 - Cron tasks: more doc 2015-09-09 21:57:15 +02:00
Luc Didry
6fab43b15b Fixes #8 - Add markdown code to copy/paste 2015-09-09 21:34:38 +02:00
Luc Didry
2f7b2f5fbb Remove debug info log 2015-09-09 21:16:21 +02:00
Luc Didry
2ca4ba1f0e Fixes #7 - make cron stop printing debug info 2015-09-09 21:15:58 +02:00
Luc Didry
62e82b8224 Put javascript in a partial template 2015-09-09 21:04:24 +02:00
Luc Didry
7b9ed1fa4a Little change to API description table 2015-08-08 12:04:15 +02:00
Luc Didry
4aa9a649be Merge branch 'thor77/lutim-api-table' 2015-08-08 11:58:02 +02:00
Thor77
6d260af932 convert api-description into table 2015-08-08 11:47:09 +02:00
Luc Didry
5bcd010055 Don't Repeat Yourself (and use partial templates) 2015-08-08 00:15:26 +02:00
Luc Didry
0f7d8e745e Delete EXIF tags without ImageMagick + add option to keep EXIF tags
Fixes #4
2015-08-08 00:13:48 +02:00
Luc Didry
1f0aa046d4 Add systemd .service file + documentation in README 2015-08-07 22:05:30 +02:00
Luc Didry
b6c3af7bc6 Fix bug preventing to store delete_at_day parameter 2015-08-06 11:01:33 +02:00
Luc Didry
c86faf208d Add DebugDumperHelper plugin 2015-08-06 11:00:34 +02:00
Luc Didry
4fe657d0d7 Merge branch 'thor77/lutim-master't push origin master 2015-08-05 15:41:39 +02:00
Thor77
023952648e add upstart-script 2015-08-05 15:27:33 +02:00
Luc Didry
baaf4ab861 Add Thor77 as contributor 2015-08-05 13:28:20 +02:00
Luc Didry
ae450a9649 Merge branch 'Thor77-patch-1' 2015-08-05 13:25:10 +02:00
Thor77
b4d06a21a0 add response-section to API
explains response parameters
2015-08-05 12:39:12 +02:00
Luc Didry
b0a19e3e42 Autorotate image + delete EXIF tags (for more privacy) 2015-08-03 00:07:28 +02:00
Luc Didry
e1840e96b0 Fix # 48 Allow to change location of the database 2015-08-02 23:34:58 +02:00
Luc Didry
e7138a40ab Update fonts
I forgot to update fonts when I switch to gitlab address, so:
* add git icon
* remove github icon
2015-08-02 22:44:08 +02:00
Luc Didry
080542fd95 Fix #47 Allow to upload svg images 2015-08-02 22:29:16 +02:00
Luc Didry
774f3ebda9 Update Changes file 2015-08-02 21:28:32 +02:00
Luc Didry
2e8f0eda2a Allow to use lutim under a sub-directory (example.org/lutim)
Fix #46 and #57
2015-08-02 21:07:50 +02:00
Luc Didry
a9ea0d35e6 Add Net::Domain::TLD to handle tld like .xyz or .link 2015-08-02 16:08:07 +02:00
Luc Didry
a049163646 Fixes #46 2015-08-02 15:41:25 +02:00
Luc Didry
2e5a3c9c0b Remove deprecated configuration option
The option had a typo. I hope people have changed their configuration.
2015-08-02 15:27:51 +02:00
Luc Didry
db50470ef8 Merge branch 'Thor77-master' 2015-08-02 15:00:27 +02:00
Luc Didry
1cb3ec09e3 Merge branch 'master' of https://github.com/Thor77/lutim into Thor77-master 2015-08-02 14:59:43 +02:00
Luc Didry
fa47a97be7 Merge branch 'i18n' into 'master'
I18n



See merge request !1
2015-08-02 14:56:48 +02:00
Luc Didry
afb377faca Update ES translation 2015-08-02 13:08:39 +02:00
Luc Didry
339cdf39b2 Use .po files for i18n + add spanish translation 2015-08-02 00:54:26 +02:00
Luc Didry
f1c096fd68 Add new dependencies 2015-06-11 21:43:06 +02:00
Luc Didry
fc28efa116 Update dependencies (cpanfile.snapshot) 2015-06-11 21:36:07 +02:00
Luc Didry
152b677614 Re-add IO::Socket::SSL as dependancy 2015-03-16 09:56:21 +01:00
Thor77
9431b60f9b Add reference to screencloud-integration 2015-02-19 15:14:58 +01:00
Luc Didry
9e27e0df59 Bump version 2014-10-03 00:40:25 +02:00
Luc Didry
0544a1b346 Update info page on rights on uploaded images 2014-10-03 00:38:47 +02:00
Luc Didry
bb1b43e215 Replace twitter page by social page (icon, description, etc)
+ small changes in README
2014-10-03 00:27:22 +02:00
Luc Didry
ad04bdd571 Add opengraph tags on twitter page.
Since the twitter page can now be embedded in Facebook and other social
networks which relies on opengraph tag, this page is now called the
social page.
2014-10-02 23:31:59 +02:00
Luc Didry
23c130750e Improve Twitter animated card (gif) (#45) 2014-09-25 01:41:42 +02:00
Luc Didry
a0b507e48e Fixes #45 + Update README.md and Changelog 2014-09-24 01:41:36 +02:00
Luc Didry
9692504096 Fix broken icon class 2014-09-12 14:29:42 +02:00
Luc Didry
8386a2f4d2 Add license mention in manifest.webapp + manifest.webapp version 2014-09-12 14:28:56 +02:00
Luc Didry
bef9dfaca3 Update description in manifest.webapp 2014-08-05 23:42:08 +02:00
Luc Didry
b71c25bf54 Close #42 2014-08-05 23:00:50 +02:00
Luc Didry
b0e5f771f2 Add Kharec as contributor 2014-07-21 16:48:12 +02:00
Sandro CAZZANIGA
2b361fce26 Fix pod description 2014-07-21 16:47:31 +02:00
Luc Didry
64e0db48f2 Change URL of official instance to the secured URL 2014-07-19 11:19:53 +02:00
298 changed files with 69438 additions and 4121 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
zanata.xml merge=ours

21
.gitignore vendored
View File

@@ -1,9 +1,20 @@
*.swp
lutim.conf
lutim.db
*.db
*.db-shm
*.db-wal
script/hypnotoad.pid
local/*
files/*
templates/data.html.ep
public/img/rezopole.png
public/img/rezopole.xcf
public/packed/*
stop-upload
themes/*
!themes/default
!themes/default/*
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
tmp/*
.zanata-cache/*
cover_db/*
*.passwd

177
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,177 @@
image: hatsoftwares/lutim-test-ci:latest
stages:
- podcheck
- carton
- carton_bdd
- tests
- cover
before_script:
- rm -f *.db
variables:
POSTGRES_DB: lutim_db
POSTGRES_USER: lutim
POSTGRES_PASSWORD: lutim_pwd
### Jobs templates
##
#
.carton_bdd_template: &carton_bdd_definition
stage: carton_bdd
retry: 2
artifacts:
paths:
- local/
dependencies:
- carton
.sqlite_template: &sqlite_definition
stage: tests
retry: 2
artifacts:
paths:
- cover_db/
dependencies:
- carton_sqlite
.pg_template: &pg_definition
stage: tests
retry: 2
artifacts:
paths:
- cover_db/
dependencies:
- carton_postgresql
services:
- name: postgres:9.6
alias: postgres
### Podcheck
##
#
podcheck:
stage: podcheck
script:
- make podcheck
### Install common dependencies
##
#
carton:
stage: carton
artifacts:
paths:
- local/
dependencies: []
script:
- carton install --deployment --without=sqlite --without=postgresql --without=minion --without=cache --without=memcached
when: always
retry: 2
### Install DB related dependencies
##
#
carton_sqlite:
<<: *carton_bdd_definition
script:
- carton install --deployment --without=postgresql --without=minion --without=cache --without=memcached
carton_postgresql:
<<: *carton_bdd_definition
script:
- carton install --deployment --without=sqlite --without=minion --without=cache --without=memcached
### SQLite tests
##
#
sqlite1:
<<: *sqlite_definition
script:
- carton install --deployment --without=postgresql --without=minion --without=cache --without=memcached
- MOJO_CONFIG=t/sqlite1.conf make test-sqlite
- MOJO_CONFIG=t/sqlite1.conf make watch
- MOJO_CONFIG=t/sqlite1.conf make cleanbdd
- MOJO_CONFIG=t/sqlite1.conf make cleanfiles
- MOJO_CONFIG=t/sqlite1.conf make stats
sqlite2:
<<: *sqlite_definition
script:
- carton install --deployment --without=postgresql --without=cache --without=memcached
- MOJO_CONFIG=t/sqlite2.conf make minion &
- sleep 3
- MOJO_CONFIG=t/sqlite2.conf make test-sqlite
- MOJO_CONFIG=t/sqlite2.conf make watch
- MOJO_CONFIG=t/sqlite2.conf make cleanbdd
- MOJO_CONFIG=t/sqlite2.conf make cleanfiles
- MOJO_CONFIG=t/sqlite2.conf make stats
sqlite3:
<<: *sqlite_definition
services:
- name: postgres:9.6
alias: postgres
script:
- carton install --deployment --without=cache --without=memcached
- export PGPASSWORD=lutim_pwd; echo 'CREATE DATABASE lutim_minion WITH OWNER lutim;' | psql -h postgres -U lutim lutim_db
- MOJO_CONFIG=t/sqlite3.conf make minion &
- sleep 3
- MOJO_CONFIG=t/sqlite3.conf make test-sqlite
- MOJO_CONFIG=t/sqlite3.conf make watch
- MOJO_CONFIG=t/sqlite3.conf make cleanbdd
- MOJO_CONFIG=t/sqlite3.conf make cleanfiles
- MOJO_CONFIG=t/sqlite3.conf make stats
### PostgreSQL tests
##
#
postgresql1:
<<: *pg_definition
script:
- carton install --deployment --without=sqlite --without=minion --without=cache --without=memcached
- MOJO_CONFIG=t/postgresql1.conf make test-pg
- MOJO_CONFIG=t/postgresql1.conf make watch
- MOJO_CONFIG=t/postgresql1.conf make cleanbdd
- MOJO_CONFIG=t/postgresql1.conf make cleanfiles
- MOJO_CONFIG=t/postgresql1.conf make stats
postgresql2:
<<: *pg_definition
script:
- carton install --deployment --without=cache --without=memcached
- MOJO_CONFIG=t/postgresql2.conf make minion &
- sleep 3
- MOJO_CONFIG=t/postgresql2.conf make test-pg
- MOJO_CONFIG=t/postgresql2.conf make watch
- MOJO_CONFIG=t/postgresql2.conf make cleanbdd
- MOJO_CONFIG=t/postgresql2.conf make cleanfiles
- MOJO_CONFIG=t/postgresql2.conf make stats
postgresql3:
<<: *pg_definition
script:
- carton install --deployment --without=sqlite --without=cache --without=memcached
- export PGPASSWORD=lutim_pwd; echo 'CREATE DATABASE lutim_minion WITH OWNER lutim;' | psql -h postgres -U lutim lutim_db
- MOJO_CONFIG=t/postgresql3.conf make minion &
- sleep 3
- MOJO_CONFIG=t/postgresql3.conf make test-pg
- MOJO_CONFIG=t/postgresql3.conf make watch
- MOJO_CONFIG=t/postgresql3.conf make cleanbdd
- MOJO_CONFIG=t/postgresql3.conf make cleanfiles
- MOJO_CONFIG=t/postgresql3.conf make stats
### Code coverage
##
#
cover:
stage: cover
script:
- make cover
coverage: '/Total .*\d+\.\d+$/'
### Push new translations strings to https://trad.framasoft.org
##
#
trads:
stage: cover
image: framasoft/push-trad:latest
dependencies: []
script:
- sed -e "s@<project-version>.*</project-version>@<project-version>$CI_COMMIT_REF_SLUG</project-version>@" -i zanata.xml
- if [ ! -z ${ZANATA_CONFIG+x} ]; then mkdir -p ${HOME}/.config; echo -e "${ZANATA_CONFIG}" > ${HOME}/.config/zanata.ini; fi
- if [ ! -z ${ZANATA_CONFIG+x} ]; then make push-locales; fi
only:
- development
- master

8
.tx/config Normal file
View File

@@ -0,0 +1,8 @@
[main]
host = https://www.transifex.com
[lutim.enpo]
source_file = lib/Lutim/I18N/en.po
source_lang = en
type = PO
file_filter = lib/Lutim/I18N/<lang>.po

19
AUTHORS.md Normal file
View File

@@ -0,0 +1,19 @@
# Lutim's authors
## Main developers
* Luc Didry, aka Sky (<http://www.fiat-tux.fr>), core developer, @framasky on [Mastodon](https://framapiaf.org/@framasky) and on [Diaspora*](https://framasphere.org/public/framasky)
* Dattaz (<http://dattaz.fr>), webapp developer, [@dat_taz](https://twitter.com/dat_taz)
## Contributors
* Jean-Bernard Marcon, aka Goofy (<https://github.com/goofy-bz>)
* Jean-Christophe Bach (<https://github.com/jcb>)
* Florian Bigard, aka Chocobozzz (<https://github.com/Chocobozzz>)
* Sandro Cazzaniga, aka Kharec (<http://sandrocazzaniga.fr>), [@Kharec](https://twitter.com/Kharec)
* Laura Arjona Reina (<https://wiki.debian.org/LauraArjona>), spanish translation
* Thor77 (<http://thor77.org>), german translation, among other things
* Quentin Pagès, occitan translation
* Alexis Clairet (<https://github.com/Turboconnard>), paste image to upload ability
* ButterflyOfFire (<https://mastodon.tetaneutral.net/@BoF>), arabic translation
* Alexander Sapozhnikov (<http://shoorick.ru>), russian translation

207
CHANGELOG Normal file
View File

@@ -0,0 +1,207 @@
Revision history for Lutim
0.11.3 2018-07-31
- Fix gallery bug
0.11.2 2018-07-31
- Fix stats graph if no upload happens in the time range
0.11.1 2018-07-30
- Add upload_enabled info to server infos endpoint
- Add log message when failing to render an image
0.11.0 2018-07-29
- Allow to install only needed deps
- Notification when copying to clipboard or deleting images
- Allow to use memcached as cache system
- Use Mojolicious::Plugin::Chi
- Gzip static assets with Mojolicious::Plugin::GzipStatic
- Fix scroll-to-top when clicking on delete image
- Add CSP header
- Add X-Content-Type-Options, X-XSS-Protection, X-Frame-Options headers
- Remove @framasky as default tweet_card_via setting
- Add a message saying how many images there is in the gallery
- Use ISO::639_1 for languages' native names
- Add CLI command to print informations about images
- Add CLI command to remove images
- Add CLI command to search images based on the uploader's IP address
- Add .zip file check in the tests
- Fix stats files place when using non-default theme
- Allow to use a fixed domain
- Add localStorage export and import feature
- Add link to generate random file in collection
- Add modal to modify expiration delay from "myfiles" page
- Add optional authentication (LDAP or htpasswd file)
0.10.4 2018-05-07
- Fix bug in cache system that would allow someone to view an image with an incorrect decryption key
0.10.3 2018-04-26
- Fix another bug on zip file creation
0.10.2 2018-04-24
- Fix bug on zip file creation
0.10.1 2018-04-15
- Fix bug on theme creation (#73)
0.10.0 2018-04-07
- PostgreSQL performance improvments
- Move some tasks to recurring instead of being in after_dispatch hook
- Built-in image cache system \o/
- Disable logs option
- Disable images' counter option
0.9.6 2018-03-12
- Update translations
0.9.5 2018-03-11
- Add russian translation, thanks to Alexander Sapozhnikov
0.9.4 2018-03-11
- Replace Twitter account URL with Mastodon one
0.9.3 2018-03-11
- Use woff2 format for HennyPenny font
0.9.2 2018-03-09
- Fix langage drop-down
- Allow to use HTML in broadcast message
- Remove old targets from Makefile
0.9.1 2018-03-09
- Fix default setting bug (db_path)
0.9.0 2018-03-09
- Added partial arabic translation (thx to ButterflyOfFire)
- Default theme is now non-fluid (ie don't take all the width of the screen)
- Use Photoswipe for the gallery instead of Unite gallery
- Use Zanata for translations (https://trad.framasoft.org)
- Add an option to personnalize proposed retention delays
- Use random Initialization Vector for encryption
- Use Mojo::SQLite instead of ORLite
- Fix various bugs
0.8.8 2018-02-07
- Fix security issues, thanks to SecuNinja
0.8.7 2017-12-22
- Fix bug if dbtype not configured in lutim.conf
0.8.6 2017-11-18
- Fix bug resulting in no EXIF tags deletion
0.8.5 2017-07-09
- Fix Henny Penny font path in css
0.8.4 2017-06-24
- Mitigate a bug using the same empty record twice
0.8.3 2017-06-15
- Fix the donuts charts in the /stats page.
0.8.2 2017-06-14
- Enforce Mojolicious::Plugin::AssetPack version
0.8.1 2017-06-13
- Fix #46
0.8 2017-06-13
- Improve statistics page
- Add database abstraction layer (#42)
- Add PostgreSQL support (#42)
- Asks for Mojolicious 7.31 minimum (to install it: `carton update`)
- Add Liberapay and Tipeee buttons
- Remove Flattr button
- Handle MOJO_CONFIG env variable (#44)
- Fix bug #39
- Add gallery constructor to "my files" list (#33)
- Handle too much images in zip download URL (#27)
- LocalStorage is now updated if an image's delay is modified
- Allow user to paste image from clipboard to upload images (#14 and !5)
- Fix #40
- Add stats in JSON format (GET /stats.json)
- Add Cache-control headers for static files
- Put almost all js/css stuff outside templates
- Allow to use Minion to increment counter (#43)
0.7.1 2016-06-21
- Fix dependency bug
0.7 2016-06-21
- Use .po files for internationalization
- Add spanish translation (thx to Laura Arjona Reina)
- Allow Lutim to be on a sub-directory (like http://example.org/lutim/) (#46 and #57)
- Remove deprecated (due to typo) option "provisionning".
- Allow to upload svg images (no thumbnail for now, ImageMagick in Debian Jessie don't work with svg) (#47)
- Allow to change location of the database (#48)
- Autorotate images
- Purge images from their EXIF tags (for more privacy)
- Provide markdown syntax at upload for using lutim's hosted images
- Now using a wiki: makes README lighter (https://framagit.org/luc/lutim/wikis/home)
- Update twitter bootstrap
- Add "Copy to clipboard" buttons to each link
- Add "Copy all links" button
- Add file extension to view link
- Add list of user's images in localStorage and a page to list the user's images
- Use cryptographically secure random generator
- Allow to set the encryption length in lutim.conf
- Add the possibility of displaying images in a gallery
- Add the possibility to download a zip file
- bugfixes
0.6 2014-10-03
- Add OpenGraph tags in social page (ex-twitter page)
- Update README.md
- Update info page
0.5 2014-09-24
- Add support for animated gif in Twitter cards (#45)
- Update README.md with Twitter integration informations
- bugfixes
0.4 2014-07-12
- Webapp ! Downloadable directly from the Lutim instance
- Configure expiration delay after uploading (#12)
- Twitter share button in the "upload success" message (#35)
0.3 2014-06-01
- Add a delete link to images (#28)
- Concatenated css and js with Mojolicious::Plugin::AssetPack
- Antiflood protection for the "Download by URL" feature (#29)
- Stats page improved
- Self-documented configuration template
- Remote port detection can now use the X-Remote-Port header if set
- Lutim now uses the X-Forwarded-Proto header to set the scheme to https if needed
The "https" option in configuration file is deprecated and will be removed in 0.4
- Optionally delete images that are no longer viewed after a configurable delay in order to avoid saturation (#27)
- Provide init script
- Update Shutter plugin
- Small bugfixes
0.2 2014-03-07
- Server-side encryption available
- Thumbnails of uploaded images in response
- Bugfixes
- HTML validity
- Stats (via cron stats command)
- Anonymize IP in DB after a delay (via cron cleanbdd command)
- Watch files directory size (via cron watch command)
- Anonymize logs (log only the senders' IP address)
- Favicon and logo
- Better MIME type detection
- Broadcast message on all pages available
- File max size configurable
- Progress bar
- More options for suppression delay
- Updated documentation
- Cross-domain API
- Upload by image URL
- Add HTTP headers Expires and Content-Cache
0.1 2014-02-15
- Image viewing link
- Image downloading link
- Image twitter card link
- Shutter Plugin
- Configurable "Hosted by" information

3
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,3 @@
# Contributing
See how to contribute on the [wiki](https://framagit.org/luc/lutim/wikis/contribute).

47
Changes
View File

@@ -1,47 +0,0 @@
Revision history for Lutim
0.4 2014-07-12
- Webapp ! Downloadable directly from the Lutim instance
- Configure expiration delay after uploading (#12)
- Twitter share button in the "upload success" message (#35)
0.3 2014-06-01
- Add a delete link to images (#28)
- Concatenated css and js with Mojolicious::Plugin::AssetPack
- Antiflood protection for the "Download by URL" feature (#29)
- Stats page improved
- Self-documented configuration template
- Remote port detection can now use the X-Remote-Port header if set
- Lutim now uses the X-Forwarded-Proto header to set the scheme to https if needed
The "https" option in configuration file is deprecated and will be removed in 0.4
- Optionally delete images that are no longer viewed after a configurable delay in order to avoid saturation (#27)
- Provide init script
- Update Shutter plugin
- Small bugfixes
0.2 2014-03-07
- Server-side encryption available
- Thumbnails of uploaded images in response
- Bugfixes
- HTML validity
- Stats (via cron stats command)
- Anonymize IP in DB after a delay (via cron cleanbdd command)
- Watch files directory size (via cron watch command)
- Anonymize logs (log only the senders' IP address)
- Favicon and logo
- Better MIME type detection
- Broadcast message on all pages available
- File max size configurable
- Progress bar
- More options for suppression delay
- Updated documentation
- Cross-domain API
- Upload by image URL
- Add HTTP headers Expires and Content-Cache
0.1 2014-02-15
- Image viewing link
- Image downloading link
- Image twitter card link
- Shutter Plugin
- Configurable "Hosted by" information

79
Makefile Normal file
View File

@@ -0,0 +1,79 @@
EXTRACTDIR=-D lib -D themes/default/templates
POT=themes/default/lib/Lutim/I18N/lutim.pot
XGETTEXT=carton exec local/bin/xgettext.pl -u
CARTON=carton exec
LUTIM=script/lutim
REAL_LUTIM=script/application
HEAD := $(shell git rev-parse --abbrev-ref HEAD)
minify:
@echo "CSS concatenation"
@cd ./themes/default/public/css/ && cat bootstrap.min.css fontello.css hennypenny.css lutim.css toastify.css | csso > common.min.css
@cd ./themes/default/public/css/ && cat animation.css uploader.css markdown.css | csso > not_stats.min.css
@cd ./themes/default/public/css/ && cat photoswipe.css default-skin/default-skin.css | csso > gallery.min.css
@cd ./themes/default/public/css/ && cat twitter.css | csso > twitter.min.css
locales:
$(XGETTEXT) $(EXTRACTDIR) -o $(POT) 2>/dev/null
push-locales:
ifeq ($(HEAD),$(filter $(HEAD),master development))
sed -e 's@<project-version>.*</project-version>@<project-version>$(HEAD)</project-version>@' -i zanata.xml && \
zanata-cli -q -B push
endif
pull-locales:
ifeq ($(HEAD),$(filter $(HEAD),master development))
sed -e 's@<project-version>.*</project-version>@<project-version>$(HEAD)</project-version>@' -i zanata.xml && \
zanata-cli -q -B pull
endif
stats-locales:
zanata-cli -q stats
podcheck:
podchecker lib/Lutim/DB/Image.pm
cover:
PERL5OPT='-Ilib/' HARNESS_PERL_SWITCHES='-MDevel::Cover' $(CARTON) cover --ignore_re '^local'
test-sqlite:
@PERL5OPT='-Ilib/' HARNESS_PERL_SWITCHES='-MDevel::Cover' $(CARTON) $(REAL_LUTIM) test
test-pg:
@PERL5OPT='-Ilib/' HARNESS_PERL_SWITCHES='-MDevel::Cover' $(CARTON) $(REAL_LUTIM) test
test: podcheck test-sqlite test-pg
clean:
rm -rf lutim.db files/
dev: minify
$(CARTON) morbo $(LUTIM) --listen http://0.0.0.0:3000 --watch lib/ --watch script/ --watch themes/ --watch lutim.conf
devlog:
multitail log/development.log
prod:
$(CARTON) hypnotoad -f $(LUTIM)
prodlog:
multitail log/production.log
minion:
$(CARTON) $(REAL_LUTIM) minion worker
create-pg-test-db:
sudo -u postgres psql -f t/create-pg-testdb.sql
stats:
$(CARTON) $(LUTIM) cron stats -m production
watch:
$(CARTON) $(LUTIM) cron watch -m production
cleanfiles:
$(CARTON) $(LUTIM) cron cleanfiles -m production
cleanbdd:
$(CARTON) $(LUTIM) cron cleanbdd -m production

291
README.md
View File

@@ -4,281 +4,66 @@
It means Let's Upload That Image.
## What does it do?
It stores images and allows you to see them, download them or use them in Twitter.
Images are indefinitly stored unless you request that they will be deleted at first view or after 24 hours / one week / one month / one year.
It stores images and allows you to see them, download them or share them on social networks. From version 0.5, the gif images can be displayed as animated gifs in Twitter, but you need an HTTPS server (Twitter requires that. Lutim detects if you have a HTTPS server and displays a static image twitter card if you don't);
Images are indefinitely stored unless you request that they will be deleted at first view or after 24 hours / one week / one month / one year.
## License
Lutim is licensed under the terms of the AGPL. See the LICENSE file.
## Official instance
You can see it working at http://lut.im.
You can see it working at https://lut.im.
## Logo
Lutim's logo is an adaptation of [Lutin](http://commons.wikimedia.org/wiki/File:Lutin_by_godo.jpg) by [Godo](http://godoillustrateur.wordpress.com/), licensed under the terms of the CC-BY-SA 3.0 license.
![Lutim's logo](http://lut.im/img/Lutim_small.png)
![Lutim's logo](https://lut.im/img/Lutim_small.png)
## Dependencies
* Carton : Perl dependencies manager, it will get what you need, so don't bother for Perl modules dependencies (but you can read the file `cpanfile` if you want).
## Wiki
```shell
sudo cpan Carton
```
or
```shell
sudo apt-get install carton
```
* But, on another hand, some modules that Carton will install need to be compiled. So you will need some tools:
```shell
sudo apt-get install build-essential libssl-dev
```
### Thumbnails dependancy
If you want to provide thumbnails of uploaded images, you have to install the *ImageMagick* image manipulation software (<http://www.imagemagick.org/>) and the Image::Magick CPAN module.
On Debian, you can do:
```shell
sudo apt-get install perlmagick
```
## Installation
After installing Carton :
```shell
git clone https://github.com/ldidry/lutim.git
cd lutim
carton install
cp lutim.conf.template lutim.conf
vi lutim.conf
```
## Configuration
The `lutim.conf.template` is self-documented but here is the options that you can set:
* **hypnotoad :** address and port to listen to, user and group which runs hypnotoad (if you run Lutim with a different user from what is defined here, be sure that the user which launchs hypnotoad is able to setuid/setgid to the defined user/group, otherwise it will not work and you'll have 100% CPU consumption. Launch hypnotoad with the root user or with the user which is defined here);
* **contact :** write something which make people able to contact you (contact form URL, email address, whatever);
* **secrets :** an array of random string. Used by Mojolicious for encrypting session cookies.
* **piwik_img :** the Piwik image provides you records of visits without javascript (better privacy than js and cookies);
* **length :** length of the random string part of image's URL (default is 8);
* **provis_step :** Lutim provisions random strings for image's URL per pack of `provis_step` (default is 5);
* **provisioning :** number of random strings to provision (default is 100);
* **hosted_by :** if someone hosts your Lutim instance, you can add some HTML (a logo for example) to make it appear on index page;
* **tweet_card_via :** a Twitter account which will appear on Twitter cards;
* **max_file_size :** well, this is explicit (default is 10Mio = 10485760 octets);
* **https :** 1 if you want to provide secure images URLs (default is 0) DEPRECATED, PASS A `X-Forwarded-Proto` HEADER TO LUTIM FROM YOUR REVERSE PROXY INSTEAD;
* **token_length :** length of the secret token used to allow people to delete their images when they want;
* **stats_day_num :** when you generate statistics with `script/lutim cron stats`, you will have stats for the last `stats_day_num` days (default is 365);
* **keep_ip_during :** when you delete IP addresses of image's senders with `script/lutim cron cleanbdd`, the IP addresses of images older than `keep_ip_during` days will be deleted (default is 365);
* **broadcast_message :** put some string (not HTML) here and this message will be displayed on all Lutim pages (not in JSON responses);
* **allowed_domains :** array of authorized domains for API calls. Example: `['http://1.example.com', 'http://2.example.com']`. If you want to authorize everyone to use the API: `['\*']`.
* **default_delay :** what is the default time limit for files? Valid values are 0, 1, 7, 30 and 365;
* **max_delay :** if defined, the images will be deleted after that delay (in days), even if they were uploaded with "no delay" (or value superior to max_delay) option and a warning message will be displayed on homepage;
* **always_encrypt :** if set to 1, all images will be encrypted.
* **delete_no_longer_viewed_files :** if set, the images which have not been viewed since `delete_no_longer_viewed_files` days will be deleted by the `script/lutim cron cleanfiles` command
## Usage
### Starting Lutim from Command line
```
carton exec hypnotoad script/lutim
```
### Starting Lutim with the init script
```
cp utilities/lutim.init /etc/init.d/lutim
cp utilities/lutim.default /etc/default/lutim
chmod +x /etc/init.d/lutim
chown root:root /etc/init.d/lutim /etc/default/lutim
vim /etc/default/lutim
/etc/init.d/lutim start
```
## Update
```
git pull
carton install
carton exec hypnotoad script/lutim
```
Yup, that's all (Mojolicious magic), it will listen at "http://127.0.0.1:8080".
For more options (interfaces, user, etc.), change the configuration in `lutim.conf` (have a look at http://mojolicio.us/perldoc/Mojo/Server/Hypnotoad#SETTINGS for the available options).
***Warning!!!***
If you want to update to Lutim **0.3**, from a previous version, you'll have to modify the database.
The official wiki contains all you need to know about Lutim (installation, API, etc.). Go to <https://framagit.org/luc/lutim/wikis/home> or clone it:
```
sqlite3 lutim.db
PRAGMA writable_schema = 1;
UPDATE SQLITE_MASTER SET SQL = 'CREATE TABLE lutim ( short TEXT PRIMARY KEY, path TEXT, footprint TEXT, enabled INTEGER, mediatype TEXT, filename TEXT, counter INTEGER, delete_at_first_view INTEGER, delete_at_day INTEGER, created_at INTEGER, created_by TEXT, last_access_at INTEGER, mod_token TEXT)' WHERE NAME = 'lutim';
PRAGMA writable_schema = 0;
git clone https://framagit.org/luc/lutim.wiki.git
```
## Reverse proxy
You can use a reverse proxy like Nginx or Varnish (or Apache with the mod_proxy module). The web is full of tutos.
Here's a valid *Nginx* configuration:
```
server {
listen 80;
root /path/to/lutim/public;
# 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
# My advice: put a varnish between nginx and Lutim, it's really useful when images are widely viewed
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;
# Lutim reads this header and understands that the current session is actually HTTPS.
# Enable it if you run a HTTPS server (in this case, don't forgot to change the listen port above)
#proxy_set_header X-Forwarded-Proto https;
# We expect the downsteam servers to redirect to the right hostname, so don't do any rewrites here.
proxy_redirect off;
}
}
```
## Cron jobs
Lutim have commands which can be used in cron jobs.
To see what commands are available:
```shell
carton exec script/lutim cron
```
### Statistics
To generate statistics which can be viewed at the address `/stats` (we need to reload hypnotoad after the stats generation):
```shell
carton exec script/lutim cron stats && carton exec hypnotoad script/lutim
```
### Delete IP adresses from database
To automatically delete the IP addresses of image's senders after a configurable delay:
```shell
carton exec script/lutim cron cleanbdd
```
### Delete expired files
To automatically delete files which availability delay is over (when you choose that your image will be deleted after 24h / one week / etc.)
If `delete_no_longer_viewed_files`, the files not viewed since `delete_no_longer_viewed_files` days will be deleted too.
```shell
carton exec script/lutim cron cleanfiles
```
### Watch the size of the files directory
To execute an action when the files directory is heavier than `max_total_size`.
The available actions are `warn` and `stop-upload`:
* `warn` prints a message on the standard out (which is normally mailed to you by `cron`) ;
* `stop-upload` prints a message on the standard out and creates the `stop-upload` file which prevents uploading and put a warn on Lutim interface ;
* **DANGEROUS OPTION!!!** `delete` prints a message on the standard out and delete older images until the files directory goes under quota.
If the files directory go under quota, the `stop-upload` file is deleted. If you want to manually prevents uploading, create a file named `stop-upload.manual`.
```shell
carton exec script/lutim cron watch
```
## Broadcast message
Set a string in the `broadcast_message` option of `lutim.conf` and reload the server with:
```shell
carton exec hypnotoad script/lutim
```
It may take a few reloads of page before the message is displayed.
## Encryption
Lutim does encryption on the server if asked to, but does not store the key.
The encryption is made on the server since Lutim is made to be usable even without javascript. If you want to add client-side encryption for javascript-enabled browsers, patches are welcome.
## API
You can add images by using the API. Here's the parameters of the `POST` request to `/` adress:.
* format: json
MANDATORY if you want to get a json response, otherwise it will send a web page
* file: the image file
MANDATORY
* delete-day: number of days you want the image to stay
OPTIONAL if 0, it will be available undefinitely
* first-view: 1
OPTIONAL if not 0, the image will be deleted at first view
Exemple with curl:
```shell
curl -F "format=json" -F "file=@/tmp/snap0001.jpg" http://lut.im
```
You can allow people to use your instance of Lutim from other domains.
Add the allowed domains as an array in the `allowed_domains` conf option. Put '`[\*]`' if you want to allow all domains.
## Shutter integration
See where Shutter (<http://en.wikipedia.org/wiki/Shutter_%28software%29>) keeps its plugins on your computer.
On my computer, it's in `/usr/share/shutter/resources/system/upload_plugins/upload`.
Then:
```
sudo cp utilities/Shutter.pm /usr/share/shutter/resources/system/upload_plugins/upload/Lutim.pm
```
And restart Shutter if it was running.
Of course, this plugin is configured for the official instance of Lutim (<http://lut.im>), feel free to edit it for your own instance.
The encryption is done on the server since Lutim is made to be usable even without javascript. If you want to add client-side encryption for javascript-enabled browsers, patches are welcome.
## Internationalization
Lutim comes with English and French languages. It will choose the language to display from the browser's settings.
If you want to add more languages, for example German:
```shell
cd lib/Lutim/I18N
cp en.pm de.pm
vim de.pm
```
Lutim comes with English, French and Spanish languages. It will choose the language to display from the browser's settings.
There's just a few sentences, so it will be quick to translate. Please consider to send me you language file in order to help the other users :smile:.
## Authors
## Others projects dependancies
Lutim is written in Perl with the [Mojolicious](http://mojolicio.us) framework, uses the [Twitter bootstrap](http://getbootstrap.com) framework to look not too ugly, [JQuery](http://jquery.com) and [JQuery File Uploader](https://github.com/danielm/uploader/) (slightly modified) to add some modernity, [Raphaël](http://raphaeljs.com/) and [morris.js](http://www.oesmith.co.uk/morris.js/) for stats graphs.
See [AUTHORS.md](AUTHORS.md) file.
## Main developers
* Luc Didry, aka Sky (<http://www.fiat-tux.fr>), core developer, [@framasky](https://twitter.com/framasky)
* Dattaz (<http://dattaz.fr>), webapp developer, [@dat_taz](https://twitter.com/dat_taz)
## Contribute!
## Contributors
* Jean-Bernard Marcon, aka Goofy (<https://github.com/goofy-bz>)
* Jean-Christophe Bach (<https://github.com/jcb>)
* Florian Bigard, aka Chocobozzz (<https://github.com/Chocobozzz>)
Please consider contributing, either by [reporting issues](https://framagit.org/luc/lutim/issues) or by helping the [internationalization](https://trad.framasoft.org/project/view/lutim). And of course, code contribution are welcome!
The details on how to contribute are on the [wiki](https://framagit.org/luc/lutim/wikis/contribute).
## Make a donation
You can make a donation to the author on [Tipeee](https://www.tipeee.com/fiat-tux) or on [Liberapay](https://liberapay.com/sky/).
## Others projects dependencies
Lutim is written in Perl with the [Mojolicious](http://mojolicio.us) framework.
It uses:
* [Twitter bootstrap](http://getbootstrap.com) framework to look not too ugly
* [JQuery](http://jquery.com) and [JQuery File Uploader](https://github.com/danielm/uploader/) (slightly modified) to add some modernity
* [Raphaël](http://raphaeljs.com/) and [morris.js](https://morrisjs.github.io/morris.js/) for stats graphs
* [freezeframe.js](http://freezeframe.chrisantonellis.com/) (slightly modified) to be able to freeze animated gifs in twitter card
* [Moment.js](http://momentjs.com/) for displaying real dates instead of unix timestamps.
* [Fontello](http://fontello.com/) and the [markdown font](https://github.com/dcurtis/markdown-mark/) for the icons, licenses for the fontello icons fonts are in `public/font/LICENSE.txt`
* [Henny Penny](https://www.google.com/fonts/specimen/Henny+Penny) font designed by Olga Umpeleva for [Brownfox](http://brownfox.org)
* [PhotoSwipe](http://photoswipe.com/) for the gallery
* [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

View File

@@ -1,15 +1,58 @@
requires 'Mojolicious';
requires 'Mojolicious', '>= 7.31';
requires 'EV';
requires 'IO::Socket::SSL';
requires 'Net::SSLeay', '>= 1.81';
requires 'Data::Validate::URI';
requires 'Net::Domain::TLD', '>= 1.75'; # Must have the last version to handle (at least) .xyz and .link
requires 'Mojolicious::Plugin::I18N';
requires 'Mojolicious::Plugin::ConfigHashMerge';
requires 'Mojolicious::Plugin::AssetPack';
requires 'ORLite';
requires 'File::Type';
requires 'Mojolicious::Plugin::DebugDumperHelper';
requires 'Mojolicious::Plugin::StaticCache';
requires 'Mojolicious::Plugin::GzipStatic';
requires 'Mojolicious::Plugin::CSPHeader';
requires 'Text::Unidecode';
requires 'DateTime';
requires 'Filesys::DiskUsage';
requires 'Switch';
requires 'Data::Validate::URI';
requires 'Crypt::CBC';
requires 'Crypt::Blowfish';
requires 'Locale::Maketext';
requires 'Locale::Maketext::Extract';
requires 'File::MimeInfo';
requires 'IO::Scalar';
requires 'Image::ExifTool';
requires 'Data::Entropy';
requires 'List::MoreUtils', '> 0.33';
requires 'Archive::Zip';
requires 'ISO::639_1';
feature 'postgresql', 'PostgreSQL support' => sub {
requires 'Mojo::Pg';
requires 'Mojolicious::Plugin::PgURLHelper';
};
feature 'sqlite', 'SQLite support' => sub {
requires 'Mojo::SQLite', '>= 3.000';
requires 'Minion::Backend::SQLite', '>= 4.001';
};
feature 'minion', 'Minion support' => sub {
requires 'Minion';
};
feature 'cache', 'Cache system' => sub {
requires 'Mojolicious::Plugin::CHI';
requires 'Data::Serializer';
};
feature 'memcached', 'Cache system using Memcached' => sub {
requires 'Mojolicious::Plugin::CHI';
requires 'CHI::Driver::Memcached';
requires 'Cache::Memcached';
};
feature 'ldap', 'LDAP authentication support' => sub {
requires 'Net::LDAP';
requires 'Mojolicious::Plugin::Authentication';
};
feature 'htpasswd', 'Htpasswd authentication support' => sub {
requires 'Apache::Htpasswd';
requires 'Mojolicious::Plugin::Authentication';
};
feature 'test' => sub {
requires 'Devel::Cover';
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,58 +0,0 @@
{
"name": "",
"css_prefix_text": "icon-",
"css_use_suffix": false,
"hinting": true,
"units_per_em": 1000,
"ascent": 850,
"glyphs": [
{
"uid": "c5fd349cbd3d23e4ade333789c29c729",
"css": "eye",
"code": 59399,
"src": "fontawesome"
},
{
"uid": "9a76bc135eac17d2c8b8ad4a5774fc87",
"css": "download",
"code": 59397,
"src": "fontawesome"
},
{
"uid": "f48ae54adfb27d8ada53d0fd9e34ee10",
"css": "trash",
"code": 59396,
"src": "fontawesome"
},
{
"uid": "2cb15eb2b295ee3c33fab1530e18a924",
"css": "bitcoin",
"code": 59395,
"src": "fontawesome"
},
{
"uid": "0f6a2573a7b6df911ed199bb63717e27",
"css": "github-circled",
"code": 59393,
"src": "fontawesome"
},
{
"uid": "627abcdb627cb1789e009c08e2678ef9",
"css": "twitter",
"code": 59392,
"src": "fontawesome"
},
{
"uid": "fccd3ea0efb711b849045bee686b1ceb",
"css": "spinner",
"code": 59398,
"src": "mfglabs"
},
{
"uid": "c71d7db10ede1349b3a8ae0293b1dbf8",
"css": "flattr",
"code": 59394,
"src": "zocial"
}
]
}

View File

@@ -1,8 +1,19 @@
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lutim;
use Mojo::Base 'Mojolicious';
use Mojo::Util qw(quote);
use LutimModel;
use Crypt::CBC;
use Mojo::IOLoop;
use Lutim::DB::Image;
use vars qw($im_loaded);
BEGIN {
eval "use Image::Magick";
if ($@) {
warn "You don't have Image::Magick installed so you won't have thumbnails.";
$im_loaded = 0;
} else {
$im_loaded = 1;
}
}
$ENV{MOJO_TMPDIR} = 'tmp';
mkdir($ENV{MOJO_TMPDIR}, 0700) unless (-d $ENV{MOJO_TMPDIR});
@@ -10,31 +21,69 @@ mkdir($ENV{MOJO_TMPDIR}, 0700) unless (-d $ENV{MOJO_TMPDIR});
sub startup {
my $self = shift;
push @{$self->commands->namespaces}, 'Lutim::Command';
$self->{wait_for_it} = {};
$self->plugin('I18N');
$self->plugin('AssetPack');
push @{$self->commands->namespaces}, 'Lutim::Command';
my $config = $self->plugin('ConfigHashMerge', {
$self->plugin('DebugDumperHelper');
my $config = $self->plugin('Config', {
default => {
provisioning => 100,
provis_step => 5,
length => 8,
always_encrypt => 0,
anti_flood_delay => 5,
tweet_card_via => '@framasky',
max_file_size => 10*1024*1024,
https => 0,
default_delay => 0,
max_delay => 0,
token_length => 24,
provisioning => 100,
provis_step => 5,
length => 8,
always_encrypt => 0,
anti_flood_delay => 5,
max_file_size => 10*1024*1024,
https => 0,
proposed_delays => '0,1,7,30,365',
default_delay => 0,
max_delay => 0,
token_length => 24,
crypto_key_length => 8,
thumbnail_size => 100,
theme => 'default',
dbtype => 'sqlite',
db_path => 'lutim.db',
max_files_in_zip => 15,
prefix => '/',
minion => {
enabled => 0,
dbtype => 'sqlite',
db_path => 'minion.db'
},
session_duration => 3600,
cache_max_size => 0,
memcached_servers => [],
quiet_logs => 0,
disable_img_stats => 0,
x_frame_options => 'DENY',
x_content_type_options => 'nosniff',
x_xss_protection => '1; mode=block',
}
});
# Default values
$config->{provisioning} = $config->{provisionning} if (defined($config->{provisionning}));
if (scalar(@{$config->{memcached_servers}})) {
$self->plugin(CHI => {
lutim_images_cache => {
driver => 'Memcached',
servers => $config->{memcached_servers},
expires_in => '1 day',
expires_on_backend => 1,
}
});
} elsif ($config->{cache_max_size} != 0) {
my $cache_max_size = 8 * 1024 * 1024 * $config->{cache_max_size};
$self->plugin(CHI => {
lutim_images_cache => {
driver => 'Memory',
global => 1,
is_size_aware => 1,
max_size => $cache_max_size,
expires_in => '1 day'
}
});
}
die "You need to provide a contact information in lutim.conf !" unless (defined($config->{contact}));
@@ -42,216 +91,55 @@ sub startup {
$self->secrets($config->{secrets});
$self->helper(
render_file => sub {
my $c = shift;
my ($filename, $path, $mediatype, $dl, $expires, $nocache, $key) = @_;
# Themes handling
shift @{$self->renderer->paths};
shift @{$self->static->paths};
if ($config->{theme} ne 'default') {
my $theme = $self->home->rel_file('themes/'.$config->{theme});
push @{$self->renderer->paths}, $theme.'/templates' if -d $theme.'/templates';
push @{$self->static->paths}, $theme.'/public' if -d $theme.'/public';
}
push @{$self->renderer->paths}, $self->home->rel_file('themes/default/templates');
push @{$self->static->paths}, $self->home->rel_file('themes/default/public');
$filename = quote($filename);
# Internationalization
my $lib = $self->home->rel_file('themes/'.$config->{theme}.'/lib');
eval qq(use lib "$lib");
$self->plugin('I18N');
my $asset;
unless ( -f $path && -r _ ) {
$c->app->log->error("Cannot read file [$path]. error [$!]");
$c->flash(
msg => $c->l('image_not_found')
);
return 500;
# Static assets gzipping
$self->plugin('GzipStatic');
# Headers
$self->plugin('Lutim::Plugin::Headers');
# Helpers
$self->plugin('Lutim::Plugin::Helpers');
$self->plugin('Lutim::Plugin::Lang');
# Minion
if ($config->{minion}->{enabled}) {
$self->config->{minion}->{dbtype} = 'sqlite' unless defined $config->{minion}->{dbtype};
if ($config->{minion}->{dbtype} eq 'sqlite') {
$self->config('minion')->{db_path} = 'minion.db' unless defined $config->{minion}->{db_path};
$self->plugin('Minion' => { SQLite => 'sqlite:'.$config->{minion}->{db_path} });
} elsif ($config->{minion}->{dbtype} eq 'postgresql') {
$self->plugin('PgURLHelper');
$self->plugin('Minion' => { Pg => $self->pg_url($config->{minion}->{'pgdb'}) });
}
$self->app->minion->add_task(
accessed => sub {
my $job = shift;
my $short = $job->args->[0];
my $time = $job->args->[1];
my $img = Lutim::DB::Image->new(app => $job->app, short => $short);
$img->accessed($time) if $img->path;
}
);
}
$mediatype =~ s/x-//;
my $headers = Mojo::Headers->new();
if ($nocache) {
$headers->add('Cache-Control' => 'no-cache, no-store, max-age=0, must-revalidate');
} else {
$headers->add('Expires' => $expires);
}
$headers->add('Content-Type' => $mediatype.';name='.$filename);
$headers->add('Content-Disposition' => $dl.';filename='.$filename);
$c->res->content->headers($headers);
$c->app->log->debug($key);
if ($key) {
$asset = $c->decrypt($key, $path);
} else {
$asset = Mojo::Asset::File->new(path => $path);
}
$c->res->content->asset($asset);
$headers->add('Content-Length' => $asset->size);
return $c->rendered(200);
}
);
$self->helper(
ip => sub {
my $c = shift;
my $ip_only = shift || 0;
my $proxy = $c->req->headers->header('X-Forwarded-For');
my $ip = ($proxy) ? $proxy : $c->tx->remote_address;
my $remote_port = (defined($c->req->headers->header('X-Remote-Port'))) ? $c->req->headers->header('X-Remote-Port') : $c->tx->remote_port;
return ($ip_only) ? $ip : "$ip remote port:$remote_port";
}
);
$self->helper(
provisioning => sub {
my $c = shift;
# Create some short patterns for provisioning
if (LutimModel::Lutim->count('WHERE path IS NULL') < $c->config->{provisioning}) {
for (my $i = 0; $i < $c->config->{provis_step}; $i++) {
if (LutimModel->begin) {
my $short;
do {
$short= $c->shortener($c->config->{length});
} while (LutimModel::Lutim->count('WHERE short = ?', $short) || $short eq 'about' || $short eq 'stats' || $short eq 'd' || $short eq 'm');
LutimModel::Lutim->create(
short => $short,
counter => 0,
enabled => 1,
delete_at_first_view => 0,
delete_at_day => 0,
mod_token => $c->shortener($c->config->{token_length})
);
LutimModel->commit;
}
}
}
}
);
$self->helper(
shortener => sub {
my $c = shift;
my $length = shift;
my @chars = ('a'..'z','A'..'Z','0'..'9');
my $result = '';
foreach (1..$length) {
$result .= $chars[rand scalar(@chars)];
}
return $result;
}
);
$self->helper(
stop_upload => sub {
my $c = shift;
if (-f 'stop-upload' || -f 'stop-upload.manual') {
$c->stash(
stop_upload => $c->l('stop_upload', $config->{contact})
);
return 1;
}
return 0;
}
);
$self->helper(
max_delay => sub {
my $c = shift;
return $c->config->{max_delay} if ($c->config->{max_delay} >= 0);
warn "max_delay set to a negative value. Default to 0.";
return 0;
}
);
$self->helper(
default_delay => sub {
my $c = shift;
return $c->config->{default_delay} if ($c->config->{default_delay} >= 0);
warn "default_delay set to a negative value. Default to 0.";
return 0;
}
);
$self->helper(
is_selected => sub {
my $c = shift;
my $num = shift;
return ($num == $c->default_delay) ? 'selected="selected"' : '';
}
);
$self->helper(
crypt => sub {
my $c = shift;
my $upload = shift;
my $filename = shift;
my $key = $c->shortener(8);
my $cipher = Crypt::CBC->new(
-key => $key,
-cipher => 'Blowfish',
-header => 'none',
-iv => 'dupajasi'
);
$cipher->start('encrypting');
my $crypt_asset = Mojo::Asset::File->new;
$crypt_asset->add_chunk($cipher->crypt($upload->slurp));
$crypt_asset->add_chunk($cipher->finish);
my $crypt_upload = Mojo::Upload->new;
$crypt_upload->filename($filename);
$crypt_upload->asset($crypt_asset);
return ($crypt_upload, $key);
}
);
$self->helper(
decrypt => sub {
my $c = shift;
my $key = shift;
my $file = shift;
my $cipher = Crypt::CBC->new(
-key => $key,
-cipher => 'Blowfish',
-header => 'none',
-iv => 'dupajasi'
);
$cipher->start('decrypting');
my $decrypt_asset = Mojo::Asset::File->new;
open(my $f, "<",$file) or die "Unable to read encrypted file: $!";
binmode $f;
while (read($f, my $buffer,1024)) {
$decrypt_asset->add_chunk($cipher->crypt($buffer));
}
$decrypt_asset->add_chunk($cipher->finish) ;
return $decrypt_asset;
}
);
$self->helper(
delete_image => sub {
my $c = shift;
my $image = shift;
unlink $image->path();
$image->update(enabled => 0);
}
);
# Hooks
$self->hook(
before_dispatch => sub {
my $c = shift;
@@ -278,23 +166,116 @@ sub startup {
}
);
$self->hook(
after_dispatch => sub {
my $c = shift;
$c->provisioning();
# Recurrent tasks
Mojo::IOLoop->recurring(5 => sub {
my $loop = shift;
# Purge expired anti-flood protection
my $wait_for_it = $c->app->{wait_for_it};
delete @{$wait_for_it}{grep { time - $wait_for_it->{$_} > $c->config->{anti_flood_delay} } keys %{$wait_for_it}} if (defined($wait_for_it));
$self->provisioning();
# Purge expired anti-flood protection
my $wait_for_it = $self->{wait_for_it};
delete @{$wait_for_it}{grep { time - $wait_for_it->{$_} > $self->config->{anti_flood_delay} } keys %{$wait_for_it}} if (defined($wait_for_it));
});
# Authentication (if configured)
if (defined($self->config('ldap')) || defined($self->config('htpasswd'))) {
if (defined($self->config('ldap'))) {
require Net::LDAP;
}
);
if (defined($self->config('htpasswd'))) {
require Apache::Htpasswd;
}
die 'Unable to read '.$self->config('htpasswd') if (defined($self->config('htpasswd')) && !-r $self->config('htpasswd'));
$self->plugin('Authentication' =>
{
autoload_user => 1,
session_key => 'Lutim',
load_user => sub {
my ($c, $username) = @_;
$self->asset('index.css' => 'css/bootstrap.min.css', 'css/fontello-embedded.css', 'css/animation.css', 'css/uploader.css', 'css/hennypenny.css', 'css/lutim.css');
$self->asset('stats.css' => 'css/bootstrap.min.css', 'css/fontello-embedded.css', 'css/morris-0.4.3.min.css', 'css/hennypenny.css', 'css/lutim.css');
$self->asset('about.css' => 'css/bootstrap.min.css', 'css/fontello-embedded.css', 'css/hennypenny.css', 'css/lutim.css');
return $username;
},
validate_user => sub {
my ($c, $username, $password, $extradata) = @_;
$self->asset('index.js' => 'js/jquery-2.1.0.min.js', 'js/bootstrap.min.js', 'js/lutim.js', 'js/dmuploader.min.js');
$self->asset('stats.js' => 'js/jquery-2.1.0.min.js', 'js/bootstrap.min.js', 'js/lutim.js', 'js/raphael-min.js', 'js/morris-0.4.3.min.js', 'js/stats.js');
if (defined($c->config('ldap'))) {
my $ldap = Net::LDAP->new($c->config->{ldap}->{uri});
my $mesg;
if (defined($c->config->{ldap}->{bind_dn}) && defined($c->config->{ldap}->{bind_pwd})) {
# connect to the ldap server using the bind credentials
$mesg = $ldap->bind(
$c->config->{ldap}->{bind_dn},
password => $c->config->{ldap}->{bind_pwd}
);
} else {
# anonymous bind
$mesg = $ldap->bind
}
if ($mesg->code) {
$c->app->log->info('[LDAP INFO] Authenticated bind failed - Login: '.$c->config->{ldap}->{bind_dn}) if defined($c->config->{ldap}->{bind_dn});
$c->app->log->error('[LDAP ERROR] Error on bind: '.$mesg->error);
return undef;
}
my $ldap_user_attr = $c->config->{ldap}->{user_attr};
my $ldap_user_filter = $c->config->{ldap}->{user_filter};
# search the ldap database for the user who is trying to login
$mesg = $ldap->search(
base => $c->config->{ldap}->{user_tree},
filter => "(&($ldap_user_attr=$username)$ldap_user_filter)"
);
if ($mesg->code) {
$c->app->log->error('[LDAP ERROR] Error on search: '.$mesg->error);
return undef;
}
# check to make sure that the ldap search returned at least one entry
my @entries = $mesg->entries;
my $entry = $entries[0];
unless (defined $entry) {
$c->app->log->info("[LDAP INFO] Authentication failed - User $username filtered out, IP: ".$c->ip);
return undef;
}
# retrieve the first user returned by the search
$c->app->log->debug("[LDAP DEBUG] Found user dn: ".$entry->dn);
# Now we know that the user exists
$mesg = $ldap->bind($entry->dn,
password => $password
);
if ($mesg->code) {
$c->app->log->info("[LDAP INFO] Authentication failed - Login: $username, IP: ".$c->ip);
$c->app->log->error('[LDAP ERROR] Authentication failed '.$mesg->error);
return undef;
}
$c->app->log->info("[LDAP INFO] Authentication successful - Login: $username, IP: ".$c->ip);
} elsif (defined($c->config('htpasswd'))) {
my $htpasswd = new Apache::Htpasswd(
{
passwdFile => $c->config('htpasswd'),
ReadOnly => 1
}
);
if (!$htpasswd->htCheckPassword($username, $password)) {
return undef;
}
$c->app->log->info("[Simple authentication successful] login: $username, IP: ".$c->ip);
}
return $username;
}
}
);
$self->app->sessions->default_expiration($self->config('session_duration'));
}
$self->defaults(layout => 'default');
@@ -303,6 +284,14 @@ sub startup {
# Router
my $r = $self->routes;
$r->add_condition(authorized => sub {
my ($r, $c, $captures) = @_;
return 1 unless (defined($self->config('ldap')) || defined($self->config('htpasswd')));
return $c->is_user_authenticated;
});
$r->options(sub {
my $c = shift;
$c->res->headers->allow('POST') if (defined($c->config->{allowed_domains}));
@@ -310,39 +299,135 @@ sub startup {
});
$r->get('/')->
to('Controller#home')->
over('authorized')->
to('Image#home')->
name('index');
$r->get('/')->
to('Authent#index');
if (defined $self->config('ldap') || defined $self->config('htpasswd')) {
# Login page
$r->get('/login')
->to('Authent#index')
->name('login');
# Authentication
$r->post('/login')
->to('Authent#login');
# Logout page
$r->get('/logout')
->to('Authent#log_out')
->name('logout');
}
$r->get('/about')->
to('Controller#about')->
to('Image#about')->
name('about');
$r->get('/infos')->
to('Image#infos')->
name('infos');
$r->get('/stats')->
to('Controller#stats')->
to('Image#stats')->
name('stats');
$r->get('/lang/:l')->
to('Image#change_lang')->
name('lang');
$r->get('/partial/:file' => sub {
my $c = shift;
$c->render(
template => 'partial/'.$c->param('file'),
format => 'js',
layout => undef,
d => {
delay_0 => $c->l('no time limit'),
delay_1 => $c->l('24 hours'),
delay_365 => $c->l('1 year')
}
);
})->name('partial');
$r->get('/gallery' => sub {
shift->render(
template => 'gallery',
);
})->name('gallery');
$r->get('/myfiles')->
over('authorized')->
name('myfiles');
$r->get('/myfiles')->
to('Authent#index');
$r->get('/manifest.webapp')->
to('Controller#webapp')->
to('Image#webapp')->
name('manifest.webapp');
$r->get('/zip')
->to('Image#zip')
->name('zip');
$r->get('/random')
->to('Image#random')
->name('random');
$r->post('/')->
to('Controller#add')->
over('authorized')->
to('Image#add')->
name('add');
$r->post('/')->
to('Authent#index');
$r->get('/d/:short/:token')->
to('Controller#delete')->
over('authorized')->
to('Image#delete')->
name('delete');
$r->get('/d/:short/:token')->
to('Authent#index');
$r->post('/m/:short/:token')->
to('Controller#modify')->
over('authorized')->
to('Image#modify')->
name('modify');
$r->post('/m/:short/:token')->
to('Authent#index');
$r->get('/:short')->
to('Controller#short')->
$r->post('/c')->
over('authorized')->
to('Image#get_counter')->
name('counter');
$r->post('/c')->
to('Authent#index');
$r->get('/about/<:short>')->
to('Image#about_img')->
name('about_img');
$r->get('/about/<:short>.<:f>')->
to('Image#about_img')->
name('about_img');
$r->get('/about/:short/<:key>.<:f>')->
to('Image#about_img')->
name('about_img');
$r->get('/<:short>.<:f>')->
to('Image#short')->
name('short');
$r->get('/:short')->
to('Image#short');
$r->get('/:short/<:key>.<:f>')->
to('Image#short');
$r->get('/:short/:key')->
to('Controller#short');
to('Image#short');
}
1;

View File

@@ -1,3 +1,4 @@
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lutim::Command::cron;
use Mojo::Base 'Mojolicious::Commands';

View File

@@ -1,7 +1,10 @@
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lutim::Command::cron::cleanbdd;
use Mojo::Base 'Mojolicious::Command';
use LutimModel;
use Mojo::Util qw(slurp decode);
use Mojo::File;
use Lutim::DB::Image;
use FindBin qw($Bin);
use File::Spec qw(catfile);
has description => 'Delete IP addresses from database after configured delay.';
has usage => sub { shift->extract_usage };
@@ -9,19 +12,26 @@ has usage => sub { shift->extract_usage };
sub run {
my $c = shift;
my $config = $c->app->plugin('ConfigHashMerge', {
my $cfile = Mojo::File->new($Bin, '..' , 'lutim.conf');
if (defined $ENV{MOJO_CONFIG}) {
$cfile = Mojo::File->new($ENV{MOJO_CONFIG});
unless (-e $cfile->to_abs) {
$cfile = Mojo::File->new($Bin, '..', $ENV{MOJO_CONFIG});
}
}
my $config = $c->app->plugin('Config', {
file => $cfile,
default => {
keep_ip_during => 365,
dbtype => 'sqlite',
}
});
my $separation = time() - $config->{keep_ip_during} * 86400;
LutimModel->do(
'UPDATE lutim SET created_by = "" WHERE path IS NOT NULL AND created_at < ?',
{},
$separation
);
my $dbi = Lutim::DB::Image->new(app => $c->app);
$dbi->clean_ips_until($separation);
}
=encoding utf8

View File

@@ -1,7 +1,11 @@
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lutim::Command::cron::cleanfiles;
use Mojo::Base 'Mojolicious::Command';
use LutimModel;
use Mojo::Util qw(slurp decode);
use Mojo::File;
use Lutim::DB::Image;
use Lutim;
use FindBin qw($Bin);
use File::Spec qw(catfile);
has description => 'Delete expired files.';
has usage => sub { shift->extract_usage };
@@ -9,22 +13,39 @@ has usage => sub { shift->extract_usage };
sub run {
my $c = shift;
my $time = time();
my @images = LutimModel::Lutim->select('WHERE enabled = 1 AND (delete_at_day * 86400) < (? - created_at) AND delete_at_day != 0', $time);
for my $image (@images) {
$c->app->delete_image($image);
my $cfile = Mojo::File->new($Bin, '..' , 'lutim.conf');
if (defined $ENV{MOJO_CONFIG}) {
$cfile = Mojo::File->new($ENV{MOJO_CONFIG});
unless (-e $cfile->to_abs) {
$cfile = Mojo::File->new($Bin, '..', $ENV{MOJO_CONFIG});
}
}
my $config = $c->app->plugin('Config', {
file => $cfile,
default => {
dbtype => 'sqlite',
}
});
my $config = $c->app->plugin('Config');
my $l = Lutim->new;
my $dbi = Lutim::DB::Image->new(app => $c->app);
$dbi->get_images_to_clean()->each(
sub {
my ($img, $num) = @_;
$l->app->delete_image($img);
}
);
if (defined($config->{delete_no_longer_viewed_files}) && $config->{delete_no_longer_viewed_files} > 0) {
$time = time() - $config->{delete_no_longer_viewed_files} * 86400;
@images = LutimModel::Lutim->select('WHERE enabled = 1 AND last_access_at < ?', $time);
for my $image (@images) {
$c->app->delete_image($image);
}
my $time = time() - $config->{delete_no_longer_viewed_files} * 86400;
$dbi->get_no_longer_viewed_files($time)->each(
sub {
my ($img, $num) = @_;
$l->app->delete_image($img);
}
);
}
}

View File

@@ -1,9 +1,15 @@
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lutim::Command::cron::stats;
use Mojo::Base 'Mojolicious::Command';
use LutimModel;
use Mojo::DOM;
use Mojo::Util qw(slurp spurt decode);
use Mojo::Util qw(encode);
use Mojo::File;
use Mojo::JSON qw(encode_json);
use Lutim::DB::Image;
use DateTime;
use FindBin qw($Bin);
use File::Spec qw(catfile);
use POSIX;
has description => 'Generate statistics about Lutim.';
has usage => sub { shift->extract_usage };
@@ -11,13 +17,30 @@ has usage => sub { shift->extract_usage };
sub run {
my $c = shift;
my $config = $c->app->plugin('ConfigHashMerge', {
my $cfile = Mojo::File->new($Bin, '..' , 'lutim.conf');
if (defined $ENV{MOJO_CONFIG}) {
$cfile = Mojo::File->new($ENV{MOJO_CONFIG});
unless (-e $cfile->to_abs) {
$cfile = Mojo::File->new($Bin, '..', $ENV{MOJO_CONFIG});
}
}
my $config = $c->app->plugin('Config', {
file => $cfile,
default => {
stats_day_num => 365
theme => 'default',
stats_day_num => 365,
dbtype => 'sqlite'
}
});
my $text = slurp('templates/data.html.ep.template');
my $template = 'themes/'.$config->{theme}.'/templates/data.html.ep.template';
unless (-e $template) {
$template = 'themes/default/templates/data.html.ep.template';
}
my $stats = {};
my $text = Mojo::File->new($template)->slurp;
my $dom = Mojo::DOM->new($text);
my $thead_tr = $dom->at('table thead tr');
my $tbody_tr = $dom->at('table tbody tr');
@@ -26,29 +49,163 @@ sub run {
my $separation = time() - $config->{stats_day_num} * 86400;
my %data;
for my $img (LutimModel::Lutim->select('WHERE path IS NOT NULL AND created_at >= ?', $separation)) {
my $time = DateTime->from_epoch(epoch => $img->created_at);
my ($year, $month, $day) = ($time->year(), $time->month(), $time->day());
my $img = Lutim::DB::Image->new(app => $c->app);
my $sca = $img->select_created_after($separation);
if (defined($data{$year}->{$month}->{$day})) {
$data{$year}->{$month}->{$day} += 1;
} else {
$data{$year}->{$month}->{$day} = 1;
}
}
$stats->{total} = $img->count_not_empty;
$stats->{average} = floor($sca->size / $config->{stats_day_num}) if $config->{stats_day_num};
$stats->{for_days} = $config->{stats_day_num};
my $total = LutimModel::Lutim->count('WHERE path IS NOT NULL AND created_at < ?', $separation);
for my $year (sort {$a <=> $b} keys %data) {
for my $month (sort {$a <=> $b} keys %{$data{$year}}) {
for my $day (sort {$a <=> $b} keys %{$data{$year}->{$month}}) {
$thead_tr->append_content('<th>'."$day/$month/$year".'</th>'."\n");
$tbody_tr->append_content('<td>'.$data{$year}->{$month}->{$day}.'</td>'."\n");
$total += $data{$year}->{$month}->{$day};
$tbody_t2->append_content('<td>'.$total.'</td>'."\n");
$sca->each(
sub {
my ($e, $num) = @_;
my $time = DateTime->from_epoch(epoch => $e->created_at);
my ($year, $month, $day) = ($time->year(), $time->month(), $time->day());
if (defined($data{$year}->{$month}->{$day})) {
$data{$year}->{$month}->{$day} += 1;
} else {
$data{$year}->{$month}->{$day} = 1;
}
}
);
my $total = $img->count_created_before($separation);
if (scalar(keys %data)) {
for my $year (sort {$a <=> $b} keys %data) {
for my $month (sort {$a <=> $b} keys %{$data{$year}}) {
for my $day (sort {$a <=> $b} keys %{$data{$year}->{$month}}) {
$thead_tr->append_content(sprintf("<th>%#.2d/%#.2d/%d</th>\n", $day, $month, $year));
$tbody_tr->append_content(sprintf("<td>%d</td>\n", $data{$year}->{$month}->{$day}));
$total += $data{$year}->{$month}->{$day};
$tbody_t2->append_content(sprintf("<td>%d</td>\n", $total));
}
}
}
} else {
my $dt = DateTime->from_epoch(epoch => $separation);
$thead_tr->append_content(sprintf("<th>%#.2d/%#.2d/%d</th>\n", $dt->day(), $dt->month(), $dt->year()));
$tbody_tr->append_content("<td>0</td>\n");
$tbody_t2->append_content(sprintf("<td>%d</td>\n", $total));
$dt = DateTime->now();
$thead_tr->append_content(sprintf("<th>%#.2d/%#.2d/%d</th>\n", $dt->day(), $dt->month(), $dt->year()));
$tbody_tr->append_content("<td>0</td>\n");
$tbody_t2->append_content(sprintf("<td>%d</td>\n", $total));
}
spurt $dom, 'templates/data.html.ep';
my $moy = $total / $config->{stats_day_num};
# Raw datas
my $template2 = 'themes/'.$config->{theme}.'/templates/raw.html.ep.template';
unless (-e $template2) {
$template2 = 'themes/default/templates/raw.html.ep.template';
}
my $text2 = Mojo::File->new($template2)->slurp;
my $dom2 = Mojo::DOM->new($text2);
my $raw = $dom2->at('table tbody');
my $raw_foot = $dom2->at('table tfoot');
my $unlimited_enabled = $img->count_delete_at_day_endis(0, 1);
my $unlimited_disabled = $img->count_delete_at_day_endis(0, 0);
my $day_enabled = $img->count_delete_at_day_endis(1, 1);
my $day_disabled = $img->count_delete_at_day_endis(1, 0);
my $week_enabled = $img->count_delete_at_day_endis(7, 1);
my $week_disabled = $img->count_delete_at_day_endis(7, 0);
my $month_enabled = $img->count_delete_at_day_endis(30, 1);
my $month_disabled = $img->count_delete_at_day_endis(30, 0);
my $year_enabled = $img->count_delete_at_day_endis(365, 1);
my $year_disabled = $img->count_delete_at_day_endis(365, 0);
my $year_disabled_in_month = $img->count_delete_at_day_endis(365, 1, time - 335 * 86400);
$stats->{unlimited} = {
enabled => $unlimited_enabled,
disabled => $unlimited_disabled
};
$stats->{day} = {
enabled => $day_enabled,
disabled => $day_disabled
};
$stats->{week} = {
enabled => $week_enabled,
disabled => $week_disabled
};
$stats->{month} = {
enabled => $month_enabled,
disabled => $month_disabled
};
$stats->{year} = {
enabled => $year_enabled,
disabled => $year_disabled
};
my $year_disabled_in_month_pct = ($year_enabled != 0) ? " (".sprintf('%.2f', 100*$year_disabled_in_month/$year_enabled)."%)" : '';
$raw->append_content("\n<tr><td><%= \$raw[4] %></td><td>".$unlimited_enabled."</td><td>".$unlimited_disabled."</td><td>ø</td></tr>\n");
$raw->append_content("<tr><td><%= \$raw[5] %></td><td>".$day_enabled."</td><td>".$day_disabled."</td><td>".$day_enabled." (100%)</td></tr>\n");
$raw->append_content("<tr><td><%= \$raw[6] %></td><td>".$week_enabled."</td><td>".$week_disabled."</td><td>".$week_enabled." (100%)</td></tr>\n");
$raw->append_content("<tr><td><%= \$raw[7] %></td><td>".$month_enabled."</td><td>".$month_disabled."</td><td>".$month_enabled." (100%)</td></tr>\n");
$raw->append_content("<tr><td><%= \$raw[8] %></td><td>".$year_enabled."</td><td>".$year_disabled."</td><td>".$year_disabled_in_month.$year_disabled_in_month_pct."</td></tr>\n");
$raw_foot->append_content("\n<tr><td><%= \$raw[9] %></td><td>".($unlimited_enabled + $day_enabled + $week_enabled + $month_enabled + $year_enabled)."</td><td>".($unlimited_disabled + $day_disabled + $week_disabled + $month_disabled + $year_disabled)."</td><td>".($day_enabled + $week_enabled + $month_enabled + $year_disabled_in_month)."</td></tr>\n");
$dom2 = <<EOF;
% my \@raw = (
% l('Image delay'),
% l('Active images'),
% l('Deleted images'),
% l('Deleted images in 30 days'),
% l('no time limit'),
% l('24 hours'),
% l('%1 days', 7),
% l('%1 days', 30),
% l('1 year'),
% l('Total')
% );
$dom2
EOF
my $js = <<EOF;
var enabled_donut = {
element: 'raw-enabled-holder',
data: [
{label: "<%= l('no time limit') %>", value: $unlimited_enabled},
{label: "<%= l('24 hours') %>", value: $day_enabled},
{label: "<%= l('%1 days', 7) %>", value: $week_enabled},
{label: "<%= l('%1 days', 30) %>", value: $month_enabled},
{label: "<%= l('1 year') %>", value: $year_enabled},
],
colors: [
'#40b489',
'#40b9b1',
'#40a1be',
'#427dc1',
'#455ac3',
]
};
var disabled_donut = {
element: 'raw-disabled-holder',
data: [
{label: "<%= l('no time limit') %>", value: $unlimited_disabled},
{label: "<%= l('24 hours') %>", value: $day_disabled},
{label: "<%= l('%1 days', 7) %>", value: $week_disabled},
{label: "<%= l('%1 days', 30) %>", value: $month_disabled},
{label: "<%= l('1 year') %>", value: $year_disabled},
],
colors: [
'#40b489',
'#40b9b1',
'#40a1be',
'#427dc1',
'#455ac3',
]
};
EOF
Mojo::File->new('themes/'.$config->{theme}.'/templates/stats.json.ep')->spurt(encode_json($stats));
Mojo::File->new('themes/'.$config->{theme}.'/templates/data.html.ep')->spurt($dom);
Mojo::File->new('themes/'.$config->{theme}.'/templates/raw.html.ep')->spurt(encode('UTF-8', $dom2));
mkdir 'themes/'.$config->{theme}.'/templates/partial/' unless -d 'themes/'.$config->{theme}.'/templates/partial/';
Mojo::File->new('themes/'.$config->{theme}.'/templates/partial/raw.js.ep')->spurt(encode('UTF-8', $js));
}
=encoding utf8

View File

@@ -1,9 +1,13 @@
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lutim::Command::cron::watch;
use Mojo::Base 'Mojolicious::Command';
use Mojo::Util qw(slurp decode);
use Filesys::DiskUsage qw/du/;
use LutimModel;
use Lutim::DB::Image;
use Lutim;
use Mojo::File;
use Switch;
use FindBin qw($Bin);
use File::Spec qw(catfile);
has description => 'Watch the files directory and take action when over quota';
has usage => sub { shift->extract_usage };
@@ -11,9 +15,18 @@ has usage => sub { shift->extract_usage };
sub run {
my $c = shift;
my $config = $c->app->plugin('ConfigHashMerge', {
my $cfile = Mojo::File->new($Bin, '..' , 'lutim.conf');
if (defined $ENV{MOJO_CONFIG}) {
$cfile = Mojo::File->new($ENV{MOJO_CONFIG});
unless (-e $cfile->to_abs) {
$cfile = Mojo::File->new($Bin, '..', $ENV{MOJO_CONFIG});
}
}
my $config = $c->app->plugin('Config', {
file => $cfile,
default => {
policy_when_full => 'warn'
policy_when_full => 'warn',
dbtype => 'sqlite',
}
});
@@ -33,11 +46,15 @@ sub run {
}
case 'delete' {
say '[Lutim cron job watch] Older files are being deleted';
my $dbi = Lutim::DB::Image->new(app => $c->app);
my $l = Lutim->new;
do {
for my $img (LutimModel::Lutim->select('WHERE path IS NOT NULL AND enabled = 1 ORDER BY created_at ASC LIMIT 50')) {
unlink $img->path() or warn "Could not unlink ".$img->path.": $!";
$img->update(enabled => 0);
}
$dbi->get_50_oldest()->each(
sub {
my ($img, $num) = @_;
$l->app->delete_image($img);
}
);
} while (du(qw/files/) > $config->{max_total_size});
}
else {
@@ -56,7 +73,7 @@ sub run {
=head1 NAME
Lutim::Command::cron::watch - Delete IP addresses from database after configured delay
Lutim::Command::cron::watch - Watch the files directory and take action when over quota
=head1 SYNOPSIS

228
lib/Lutim/Command/image.pm Normal file
View File

@@ -0,0 +1,228 @@
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lutim::Command::image;
use Mojo::Base 'Mojolicious::Command';
use Mojo::Util qw(getopt);
use Mojo::Collection 'c';
use Lutim::DB::Image;
use FindBin qw($Bin);
use File::Spec qw(catfile);
has description => 'Manage stored images';
has usage => sub { shift->extract_usage };
my $csv_header = 0;
sub run {
my $c = shift;
my @args = @_;
my $cfile = Mojo::File->new($Bin, '..' , 'lutim.conf');
if (defined $ENV{MOJO_CONFIG}) {
$cfile = Mojo::File->new($ENV{MOJO_CONFIG});
unless (-e $cfile->to_abs) {
$cfile = Mojo::File->new($Bin, '..', $ENV{MOJO_CONFIG});
}
}
my $config = $c->app->plugin('Config', {
file => $cfile,
default => {
provisioning => 100,
provis_step => 5,
length => 8,
always_encrypt => 0,
anti_flood_delay => 5,
max_file_size => 10*1024*1024,
https => 0,
proposed_delays => '0,1,7,30,365',
default_delay => 0,
max_delay => 0,
token_length => 24,
crypto_key_length => 8,
thumbnail_size => 100,
theme => 'default',
dbtype => 'sqlite',
db_path => 'lutim.db',
max_files_in_zip => 15,
prefix => '/',
minion => {
enabled => 0,
dbtype => 'sqlite',
db_path => 'minion.db'
},
cache_max_size => 0,
memcached_servers => [],
quiet_logs => 0,
disable_img_stats => 0,
x_frame_options => 'DENY',
x_content_type_options => 'nosniff',
x_xss_protection => '1; mode=block',
}
});
if (scalar(@{$config->{memcached_servers}})) {
$c->app->plugin(CHI => {
lutim_images_cache => {
driver => 'Memcached',
servers => $config->{memcached_servers},
expires_in => '1 day',
expires_on_backend => 1,
}
});
}
getopt \@args,
'i|info=s{1,}' => \my @info,
'c|csv' => \my $csv,
'r|remove=s{1,}' => \my @remove,
'y|yes' => \my $yes,
'q|quiet' => \my $quiet,
's|search=s' => \my $ip
;
if (scalar @info) {
c(@info)->each(
sub {
my ($e, $num) = @_;
my $i = get_short($c, $e);
print_infos($i, $csv) if $i;
}
);
}
if (scalar @remove) {
c(@remove)->each(
sub {
my ($e, $num) = @_;
my $i = get_short($c, $e);
if ($i) {
if ($i->enabled) {
print_infos($i, 0) unless $quiet;
delete_short($c, $i, $yes);
} else {
say sprintf('The image %s is already disabled', $e);
}
}
}
);
if ($config->{cache_max_size} && !scalar(@{$config->{memcached_servers}})) {
say "\nPlease reload Lutim to be sure that the deleted images are not in the cache anymore.";
}
}
if ($ip) {
my $u = Lutim::DB::Image->new(app => $c->app)->search_created_by($ip);
my @shorts;
$u->each(sub {
my ($e, $num) = @_;
push @shorts, $e->short;
print_infos($e, $csv);
});
say sprintf('%d matching URLs', $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;
}
}
sub get_short {
my $c = shift;
my $short = shift;
my $i = Lutim::DB::Image->new(app => $c->app, short => $short);
if ($i->path) {
return $i;
} else {
say sprintf('Sorry, unable to find an image with short = %s', $short);
return undef;
}
}
sub print_infos {
my $i = shift;
my $csv = shift;
my $msg;
if ($i) {
if ($csv) {
if (!$csv_header) {
say 'short,path,footprint,enabled,mediatype,filename,counter,delete_at_first_view,delete_at_day,created_at,created_by,last_access_at,width,height';
$csv_header = 1;
}
$msg = '"%s","%s","%s",%d,"%s","%s",%d,"%s",%d,"%s","%s","%s",%d,%d';
} else {
$msg = <<EOF;
%s
path : %s
footprint : %s
enabled : %d
mediatype : %s
filename : %s
counter : %d
delete_at_first_view : %d
delete_at_day : %d
created_at : %s
created_by : %s
last_access_at : %s
width : %d
height : %d
EOF
}
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime($i->created_at);
my $created_at = sprintf('%d-%d-%d %d:%d:%d GMT', $year + 1900, ++$mon, $mday, $hour, $min, $sec);
my $last_access_at = '';
if ($i->last_access_at) {
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime($i->last_access_at);
$last_access_at = sprintf('%d-%d-%d %d:%d:%d GMT', $year + 1900, ++$mon, $mday, $hour, $min, $sec);
}
say sprintf($msg,
$i->short,
$i->path,
$i->footprint,
$i->enabled,
$i->mediatype,
$i->filename,
$i->counter,
$i->delete_at_first_view,
$i->delete_at_day,
$created_at,
$i->created_by,
$last_access_at,
$i->width,
$i->height
);
}
}
sub delete_short {
my $c = shift;
my $i = shift;
my $y = shift;
my $confirm = ($y) ? 'yes' : undef;
unless (defined $confirm) {
printf('Are you sure you want to remove this image (%s) ? [N/y] ', $i->short);
$confirm = <STDIN>;
chomp $confirm;
}
if ($confirm =~ m/^y(es)?$/i) {
$c->app->delete_image($i);
} else {
say 'Answer was not "y" or "yes". Aborting deletion.';
}
}
=encoding utf8
=head1 NAME
Lutim::Command::image - Manage URL in Lutim's database
=head1 SYNOPSIS
Usage:
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)
=cut
1;

124
lib/Lutim/Command/theme.pm Normal file
View File

@@ -0,0 +1,124 @@
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lutim::Command::theme;
use Mojo::Base 'Mojolicious::Commands';
use FindBin qw($Bin);
use File::Spec qw(catfile cat dir);
use File::Path qw(make_path);
has description => 'Create new theme skeleton.';
has usage => sub { shift->extract_usage };
has message => sub { shift->extract_usage . "\nCreate new theme skeleton:\n" };
has namespaces => sub { ['Lutim::Command::theme'] };
sub run {
my $c = shift;
my $name = shift;
unless (defined $name) {
say $c->extract_usage;
exit 1;
}
my $home = File::Spec->catdir($Bin, '..', 'themes', $name);
unless (-d $home) {
# Create skeleton
mkdir $home;
mkdir File::Spec->catdir($home, 'public');
make_path(File::Spec->catdir($home, 'templates', 'layouts'));
make_path(File::Spec->catdir($home, 'lib', 'Lutim', 'I18N'));
my $i18n = <<EOF;
# 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;
EOF
open my $f, '>', File::Spec->catfile($home, 'lib', 'Lutim', 'I18N.pm') or die "Unable to open $home/lib/Lutim/I18N.pm: $!";
print $f $i18n;
close $f;
my $makefile = <<EOF;
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)
EOF
open $f, '>', File::Spec->catfile($home, 'Makefile') or die "Unable to open $home/Makefile: $!";
print $f $makefile;
close $f;
open $f, '>', File::Spec->catfile($home, '.gitignore') or die "Unable to open $home/.gitignore: $!";
print $f "public/packed/\ntemplates/data.html.ep";
close $f;
} else {
say "$name theme already exists. Aborting.";
exit 1;
}
}
=encoding utf8
=head1 NAME
Lutim::Command::theme - Create new theme skeleton.
=head1 SYNOPSIS
Usage: script/lutim theme THEME_NAME
Your new theme will be available in the themes directory.
=cut
1;

View File

@@ -1,486 +0,0 @@
# vim:set sw=4 ts=4 sts=4 expandtab:
package Lutim::Controller;
use Mojo::Base 'Mojolicious::Controller';
use Mojo::Util qw(url_unescape b64_encode);
use DateTime;
use File::Type;
use Digest::file qw(digest_file_hex);
use Text::Unidecode;
use Data::Validate::URI qw(is_http_uri is_https_uri);
use vars qw($im_loaded);
BEGIN {
eval "use Image::Magick";
if ($@) {
warn "You don't have Image::Magick installed so you won't have thumbnails.";
$im_loaded = 0;
} else {
$im_loaded = 1;
}
}
sub home {
my $c = shift;
$c->render(
template => 'index',
max_file_size => $c->req->max_message_size
);
$c->on(finish => sub {
my $c = shift;
$c->app->log->info('[HIT] someone visited site index');
}
);
}
sub about {
shift->render(template => 'about');
}
sub stats {
shift->render(
template => 'stats',
total => LutimModel::Lutim->count('WHERE path IS NOT NULL')
);
}
sub webapp {
my $c = shift;
my $headers = Mojo::Headers->new();
$headers->add('Content-Type' => 'application/x-web-app-manifest+json');
$c->res->content->headers($headers);
$c->render(
template => 'manifest',
format => 'webapp'
);
}
sub modify {
my $c = shift;
my $short = $c->param('short');
my $token = $c->param('token');
my $url = $c->param('url');
my @images = LutimModel::Lutim->select('WHERE short = ? AND path IS NOT NULL', $short);
if (scalar(@images)) {
my $image = $images[0];
my $msg;
if ($image->mod_token() ne $token || $token eq '') {
$msg = $c->l('invalid_token');
} else {
$c->app->log->info('[MODIFICATION] someone modify '.$image->filename.' with token method (path: '.$image->path.')');
$image->update(
delete_at_day => ($c->param('delete-day') && $c->param('delete-day') <= $c->max_delay) ? $c->param('delete-day') : $c->max_delay,
delete_at_first_view => ($c->param('first-view')) ? 1 : 0,
);
$msg = $c->l('image_delay_modified');
if (defined($c->param('format')) && $c->param('format') eq 'json') {
return $c->render(
json => {
success => Mojo::JSON->true,
msg => $msg
}
);
} else {
$msg .= ' (<a href="'.$url.'">'.$url.'</a>)' unless (!defined($url));
$c->flash(
success => $msg
);
return $c->redirect_to('/');
}
}
if (defined($c->param('format')) && $c->param('format') eq 'json') {
return $c->render(
json => {
success => Mojo::JSON->false,
msg => $msg
}
);
} else {
$c->flash(
msg => $msg
);
return $c->redirect_to('/');
}
} else {
$c->app->log->info('[UNSUCCESSFUL] someone tried to modify '.$short.' but it does\'nt exist.');
# Image never existed
my $msg = $c->l('image_mod_not_found', $short);
if (defined($c->param('format')) && $c->param('format') eq 'json') {
return $c->render(
json => {
success => Mojo::JSON->false,
msg => $msg
}
);
} else {
$c->flash(
msg => $msg
);
return $c->redirect_to('/');
}
}
}
sub delete {
my $c = shift;
my $short = $c->param('short');
my $token = $c->param('token');
my @images = LutimModel::Lutim->select('WHERE short = ? AND path IS NOT NULL', $short);
if (scalar(@images)) {
my $image = $images[0];
my $msg;
if ($image->mod_token() ne $token || $token eq '') {
$msg = $c->l('invalid_token');
} elsif ($image->enabled() == 0) {
$msg = $c->l('already_deleted', $image->filename);
} else {
$c->app->log->info('[DELETION] someone made '.$image->filename.' removed with token method (path: '.$image->path.')');
$c->delete_image($image);
$c->flash(
success => $c->l('image_deleted', $image->filename)
);
return $c->redirect_to('/');
}
$c->flash(
msg => $msg
);
return $c->redirect_to('/');
} else {
$c->app->log->info('[UNSUCCESSFUL] someone tried to delete '.$short.' but it does\'nt exist.');
# Image never existed
$c->render_not_found;
}
}
sub add {
my $c = shift;
my $upload = $c->param('file');
my $file_url = $c->param('lutim-file-url');
if(!defined($c->stash('stop_upload'))) {
if (defined($file_url) && $file_url) {
if (is_http_uri($file_url) || is_https_uri($file_url)) {
# Anti-flood protection
my $ip = $c->ip(1);
while (defined($c->app->{wait_for_it}->{$ip}) && (time - $c->app->{wait_for_it}->{$ip}) <= $c->config->{anti_flood_delay} ) {
sleep($c->config->{anti_flood_delay});
}
my $ua = Mojo::UserAgent->new;
my $tx = $ua->get($file_url => {DNT => 1});
if (my $res = $tx->success) {
$file_url = url_unescape $file_url;
$file_url =~ m#^.*/([^/]*)$#;
my $filename = $1;
$filename = 'uploaded.image' unless (defined($filename));
$filename .= '.image' if (index($filename, '.') == -1);
$upload = Mojo::Upload->new(
asset => $res->content->asset,
filename => $filename
);
$c->app->{wait_for_it}->{$ip} = time;
} elsif ($tx->res->is_limit_exceeded) {
my $msg = $c->l('file_too_big', $tx->res->max_message_size);
if (defined($c->param('format')) && $c->param('format') eq 'json') {
return $c->render(
json => {
success => Mojo::JSON->false,
msg => {
filename => $file_url,
msg => $msg
}
}
);
} else {
$c->flash(msg => $msg);
$c->flash(filename => $upload->filename);
return $c->redirect_to('/');
}
} else {
my $msg = $c->l('download_error');
$c->app->log->warn('[DOWNLOAD ERROR]'.$c->dumper($tx->error));
if (defined($c->param('format')) && $c->param('format') eq 'json') {
return $c->render(
json => {
success => Mojo::JSON->false,
msg => {
filename => $file_url,
msg => $msg
}
}
);
} else {
$c->flash(msg => $msg);
$c->flash(filename => $file_url);
return $c->redirect_to('/');
}
}
} else {
my $msg = $c->l('no_valid_url');
if (defined($c->param('format')) && $c->param('format') eq 'json') {
return $c->render(
json => {
success => Mojo::JSON->false,
msg => {
filename => $file_url,
msg => $msg
}
}
);
} else {
$c->flash(msg => $msg);
$c->flash(filename => $file_url);
return $c->redirect_to('/');
}
}
}
my $ft = File::Type->new();
my $mediatype = $ft->mime_type($upload->slurp());
my $ip = $c->ip;
my ($msg, $short, $real_short, $token, $thumb);
# Check file type
if (index($mediatype, 'image/') >= 0) {
# Create directory if needed
mkdir('files', 0700) unless (-d 'files');
if ($c->req->is_limit_exceeded) {
$msg = $c->l('file_too_big', $c->req->max_message_size);
if (defined($c->param('format')) && $c->param('format') eq 'json') {
return $c->render(
json => {
success => Mojo::JSON->false,
msg => $msg
}
);
} else {
$c->flash(msg => $msg);
$c->flash(filename => $upload->filename);
return $c->redirect_to('/');
}
}
if(LutimModel->begin) {
my @records = LutimModel::Lutim->select('WHERE path IS NULL LIMIT 1');
if (scalar(@records)) {
# Save file and create record
my $filename = unidecode($upload->filename);
my $ext = ($filename =~ m/([^.]+)$/)[0];
my $path = 'files/'.$records[0]->short.'.'.$ext;
if ($im_loaded) {
my $im = Image::Magick->new;
$im->BlobToImage($upload->slurp);
$im->Resize(geometry=>'x85');
$thumb = 'data:'.$mediatype.';base64,';
$thumb .= b64_encode $im->ImageToBlob();
}
my $key;
if ($c->param('crypt') || $c->config->{always_encrypt}) {
($upload, $key) = $c->crypt($upload, $filename);
}
$upload->move_to($path);
$records[0]->update(
path => $path,
filename => $filename,
mediatype => $mediatype,
footprint => digest_file_hex($path, 'SHA-512'),
enabled => 1,
delete_at_day => ($c->param('delete-day') && $c->param('delete-day') <= $c->max_delay) ? $c->param('delete-day') : $c->max_delay,
delete_at_first_view => ($c->param('first-view')) ? 1 : 0,
created_at => time(),
created_by => $ip
);
# Log image creation
$c->app->log->info('[CREATION] '.$ip.' pushed '.$filename.' (path: '.$path.')');
# Give url to user
$short = $records[0]->short;
$real_short = $short;
if (!defined($records[0]->mod_token)) {
$records[0]->update(
mod_token => $c->shortener($c->config->{token_length})
);
}
$token = $records[0]->mod_token;
$short .= '/'.$key if (defined($key));
} else {
# Houston, we have a problem
$msg = $c->l('no_more_short', $c->config->{contact});
}
}
LutimModel->commit;
} else {
$msg = $c->l('no_valid_file', $upload->filename);
}
if (defined($c->param('format')) && $c->param('format') eq 'json') {
if (defined($short)) {
$msg = {
filename => $upload->filename,
short => $short,
real_short => $real_short,
token => $token,
thumb => $thumb
};
} else {
$msg = {
filename => $upload->filename,
msg => $msg
};
}
return $c->render(
json => {
success => (defined($short)) ? Mojo::JSON->true : Mojo::JSON->false,
msg => $msg
}
);
} else {
if ((defined($msg))) {
$c->flash(msg => $msg);
$c->flash(filename => $upload->filename);
return $c->redirect_to('/');
} else {
$c->stash(short => $short) if (defined($short));
$c->stash(real_short => $real_short);
$c->stash(token => $token);
$c->stash(thumb => $thumb);
$c->stash(filename => $upload->filename);
return $c->render(
template => 'index',
max_file_size => $c->req->max_message_size
);
}
}
} else {
if (defined($c->param('format')) && $c->param('format') eq 'json') {
return $c->render(
json => {
success => Mojo::JSON->false,
msg => {
filename => $upload->filename,
msg => $c->stash('stop_upload')
}
}
);
} else {
$c->flash(msg => $c->stash('stop_upload'));
$c->flash(filename => $upload->filename);
return $c->redirect_to('/');
}
}
}
sub short {
my $c = shift;
my $short = $c->param('short');
my $touit = $c->param('t');
my $key = $c->param('key');
my $dl = (defined($c->param('dl'))) ? 'attachment' : 'inline';
my @images = LutimModel::Lutim->select('WHERE short = ? AND ENABLED = 1 AND path IS NOT NULL', $short);
if (scalar(@images)) {
if($images[0]->delete_at_day && $images[0]->created_at + $images[0]->delete_at_day * 86400 <= time()) {
# Log deletion
$c->app->log->info('[DELETION] someone tried to view '.$images[0]->filename.' but it has been removed by expiration (path: '.$images[0]->path.')');
# Delete image
$c->delete_image($images[0]);
# Warn user
$c->flash(
msg => $c->l('image_not_found')
);
return $c->redirect_to('/');
}
my $test;
if (defined($touit)) {
$test = 1;
my $short = $images[0]->short;
$short .= '/'.$key if (defined($key));
return $c->render(
template => 'twitter',
layout => undef,
short => $short,
filename => $images[0]->filename
);
} else {
# Delete image if needed
if ($images[0]->delete_at_first_view && $images[0]->counter >= 1) {
# Log deletion
$c->app->log->info('[DELETION] someone made '.$images[0]->filename.' removed (path: '.$images[0]->path.')');
# Delete image
$c->delete_image($images[0]);
$c->flash(
msg => $c->l('image_not_found')
);
return $c->redirect_to('/');
} else {
my $expires = ($images[0]->delete_at_day) ? $images[0]->delete_at_day : 360;
my $dt = DateTime->from_epoch( epoch => $expires * 86400 + $images[0]->created_at);
$dt->set_time_zone('GMT');
$expires = $dt->strftime("%a, %d %b %Y %H:%M:%S GMT");
$test = $c->render_file($images[0]->filename, $images[0]->path, $images[0]->mediatype, $dl, $expires, $images[0]->delete_at_first_view, $key);
}
}
if ($test != 500) {
# Update counter
$c->on(finish => sub {
# Log access
$c->app->log->info('[VIEW] someone viewed '.$images[0]->filename.' (path: '.$images[0]->path.')');
# Update record
my $counter = $images[0]->counter + 1;
$images[0]->update(counter => $counter);
$images[0]->update(last_access_at => time());
# Delete image if needed
if ($images[0]->delete_at_first_view) {
# Log deletion
$c->app->log->info('[DELETION] someone made '.$images[0]->filename.' removed (path: '.$images[0]->path.')');
# Delete image
$c->delete_image($images[0]);
}
});
}
} else {
@images = LutimModel::Lutim->select('WHERE short = ? AND ENABLED = 0 AND path IS NOT NULL', $short);
if (scalar(@images)) {
# Log access try
$c->app->log->info('[NOT FOUND] someone tried to view '.$short.' but it does\'nt exist anymore.');
# Warn user
$c->flash(
msg => $c->l('image_not_found')
);
return $c->redirect_to('/');
} else {
# Image never existed
$c->render_not_found;
}
}
}
1;

View File

@@ -0,0 +1,76 @@
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lutim::Controller::Authent;
use Mojo::Base 'Mojolicious::Controller';
sub index {
my $c = shift;
if ($c->is_user_authenticated) {
$c->redirect_to('index');
} else {
$c->render(template => 'login');
}
}
sub login {
my $c = shift;
my $login = $c->param('login');
my $pwd = $c->param('password');
my $ref = $c->req->headers->referrer;
if($c->authenticate($login, $pwd)) {
$c->respond_to(
json => sub {
my $c = shift;
$c->render(
json => {
success => Mojo::JSON->true,
msg => $c->l('You have been successfully logged in.')
}
);
},
any => sub {
$c->redirect_to($ref);
}
);
} else {
my $msg = $c->l('Please, check your credentials: unable to authenticate.');
$c->respond_to(
json => sub {
my $c = shift;
$c->render(
json => {
success => Mojo::JSON->false,
msg => $msg
}
);
},
any => sub {
$c->stash(msg => $msg);
$c->render(template => 'login')
}
);
}
}
sub log_out {
my $c = shift;
if ($c->is_user_authenticated) {
$c->logout;
}
$c->respond_to(
json => sub {
my $c = shift;
$c->render(
json => {
success => Mojo::JSON->true,
msg => $c->l('You have been successfully logged out.')
}
);
},
any => sub {
$c->render(template => 'logout');
}
);
}
1;

View File

@@ -0,0 +1,805 @@
# vim:set sw=4 ts=4 sts=4 expandtab:
package Lutim::Controller::Image;
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;
use Digest::file qw(digest_file_hex);
use Text::Unidecode;
use Data::Validate::URI qw(is_http_uri is_https_uri);
use File::MimeInfo::Magic qw(mimetype extensions);
use IO::Scalar;
use Image::ExifTool;
use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
use Data::Entropy qw(entropy_source);
use vars qw($im_loaded);
BEGIN {
eval "use Image::Magick";
if ($@) {
warn "You don't have Image::Magick installed so you won't have thumbnails.";
$im_loaded = 0;
} else {
$im_loaded = 1;
}
}
sub home {
my $c = shift;
$c->render(
template => 'index',
max_file_size => $c->req->max_message_size
);
$c->on(finish => sub {
my $c = shift;
$c->app->log->info('[HIT] someone visited site index') unless $c->config('quiet_logs');
}
);
}
sub about {
shift->render(template => 'about');
}
sub change_lang {
my $c = shift;
my $l = $c->param('l');
$c->cookie(lutim_lang => $l, { path => $c->config('prefix') });
if ($c->req->headers->referrer) {
return $c->redirect_to($c->req->headers->referrer);
} else {
return $c->redirect_to('/');
}
}
sub stats {
my $c = shift;
my $img = Lutim::DB::Image->new(app => $c);
$c->render(
template => 'stats',
total => $img->count_not_empty
);
}
sub infos {
my $c = shift;
$c->render(
json => {
broadcast_message => $c->config('broadcast_message'),
image_magick => ($im_loaded) ? true : false,
contact => $c->config('contact'),
max_file_size => $c->config('max_file_size'),
default_delay => $c->config('default_delay'),
max_delay => $c->config('max_delay'),
always_encrypt => ($c->config('always_encrypt')) ? true : false,
upload_enabled => ($c->app->stop_upload()) ? false : true,
}
);
}
sub about_img {
my $c = shift;
my $short = $c->param('short');
my $image = Lutim::DB::Image->new(app => $c->app, short => $short);
if ($image->enabled && $image->path) {
return $c->render(
json => {
success => true,
data => {
width => $image->width,
height => $image->height,
}
}
);
} else {
return $c->render(
json => {
success => false,
msg => $c->l('Unable to find the image %1.', $short)
}
);
}
}
sub webapp {
my $c = shift;
my $headers = Mojo::Headers->new();
$headers->add('Content-Type' => 'application/x-web-app-manifest+json');
$c->res->content->headers($headers);
$c->render(
template => 'manifest',
format => 'webapp'
);
}
sub get_counter {
my $c = shift;
my $short = $c->param('short');
my $token = $c->param('token');
my $img = Lutim::DB::Image->new(app => $c->app, short => $short);
if (defined($img->mod_token) && $img->mod_token eq $token) {
return $c->render(
json => {
success => true,
counter => $img->counter,
enabled => ($img->enabled) ? true : false
}
);
}
$c->render(
json => {
success => false,
msg => $c->l('Unable to get counter')
}
);
}
sub modify {
my $c = shift;
my $short = $c->param('short');
my $token = $c->param('token');
my $url = $c->param('url');
my $image = Lutim::DB::Image->new(app => $c->app, short => $short);
if ($image->path) {
my $msg;
if ($image->mod_token ne $token || $token eq '') {
$msg = $c->l('The delete token is invalid.');
} else {
$c->app->log->info('[MODIFICATION] someone modify '.$image->filename.' with token method (path: '.$image->path.')') unless $c->config('quiet_logs');
$image->delete_at_day(($c->param('delete-day') && ($c->param('delete-day') <= $c->max_delay || $c->max_delay == 0)) ? $c->param('delete-day') : $c->max_delay);
$image->delete_at_first_view(($c->param('first-view')) ? 1 : 0);
$image->write;
$msg = $c->l('The image\'s delay has been successfully modified');
if (defined($c->param('format')) && $c->param('format') eq 'json') {
return $c->render(
json => {
success => Mojo::JSON->true,
msg => $msg
}
);
} else {
$msg .= ' (<a href="'.$url.'">'.$url.'</a>)' unless (!defined($url));
$c->flash(
success => $msg
);
return $c->redirect_to('/');
}
}
if (defined($c->param('format')) && $c->param('format') eq 'json') {
return $c->render(
json => {
success => Mojo::JSON->false,
msg => $msg
}
);
} else {
$c->flash(
msg => $msg
);
return $c->redirect_to('/');
}
} else {
$c->app->log->info('[UNSUCCESSFUL] someone tried to modify '.$short.' but it does\'nt exist.') unless $c->config('quiet_logs');
# Image never existed
my $msg = $c->l('Unable to find the image %1.', $short);
if (defined($c->param('format')) && $c->param('format') eq 'json') {
return $c->render(
json => {
success => Mojo::JSON->false,
msg => $msg
}
);
} else {
$c->flash(
msg => $msg
);
return $c->redirect_to('/');
}
}
}
sub delete {
my $c = shift;
my $short = $c->param('short');
my $token = $c->param('token');
my $image = Lutim::DB::Image->new(app => $c->app, short => $short);
if ($image->path) {
my $msg;
if ($image->mod_token ne $token || $token eq '') {
$msg = $c->l('The delete token is invalid.');
} elsif ($image->enabled() == 0) {
$msg = $c->l('The image %1 has already been deleted.', $image->filename);
} else {
$c->app->log->info('[DELETION] someone made '.$image->filename.' removed with token method (path: '.$image->path.')') unless $c->config('quiet_logs');
$c->delete_image($image);
return $c->respond_to(
json => {
json => {
success => true,
msg => $c->l('The image %1 has been successfully deleted', $image->filename)
}
},
any => sub {
$c->flash(
success => $c->l('The image %1 has been successfully deleted', $image->filename)
);
return $c->redirect_to('/');
}
);
}
return $c->respond_to(
json => {
json => {
success => false,
msg => $msg
}
},
any => sub {
$c->flash(
msg => $msg
);
return $c->redirect_to('/');
}
);
} else {
$c->app->log->info('[UNSUCCESSFUL] someone tried to delete '.$short.' but it does\'nt exist.') unless $c->config('quiet_logs');
# Image never existed
return $c->respond_to(
json => {
json => {
success => false,
msg => $c->l('Unable to find the image %1.', $short)
}
},
any => sub {
$c->helpers->reply->not_found;
}
);
}
}
sub add {
my $c = shift;
my $upload = $c->param('file');
my $file_url = $c->param('lutim-file-url');
my $keep_exif = $c->param('keep-exif');
if(!defined($c->stash('stop_upload'))) {
if (defined($file_url) && $file_url) {
if (is_http_uri($file_url) || is_https_uri($file_url)) {
# Anti-flood protection
my $ip = $c->ip(1);
while (defined($c->app->{wait_for_it}->{$ip}) && (time - $c->app->{wait_for_it}->{$ip}) <= $c->config->{anti_flood_delay} ) {
sleep($c->config->{anti_flood_delay});
}
my $ua = Mojo::UserAgent->new;
my $tx = $ua->get($file_url => {DNT => 1});
if (my $res = $tx->success) {
$file_url = url_unescape $file_url;
$file_url =~ m#^.*/([^/?]*)\??.*$#;
my $filename = $1;
$filename = 'uploaded.image' unless (defined($filename));
$filename .= '.image' if (index($filename, '.') == -1);
$upload = Mojo::Upload->new(
asset => $res->content->asset,
filename => $filename
);
$c->app->{wait_for_it}->{$ip} = time;
} elsif ($tx->res->is_limit_exceeded) {
my $msg = $c->l('The file exceed the size limit (%1)', $tx->res->max_message_size);
if (defined($c->param('format')) && $c->param('format') eq 'json') {
return $c->render(
json => {
success => Mojo::JSON->false,
msg => {
filename => $file_url,
msg => $msg
}
}
);
} else {
$c->flash(msg => $msg);
$c->flash(filename => $upload->filename);
return $c->redirect_to('/');
}
} else {
my $msg = $c->l('An error occured while downloading the image.');
$c->app->log->warn('[DOWNLOAD ERROR]'.$c->dumper($tx->error));
if (defined($c->param('format')) && $c->param('format') eq 'json') {
return $c->render(
json => {
success => Mojo::JSON->false,
msg => {
filename => $file_url,
msg => $msg
}
}
);
} else {
$c->flash(msg => $msg);
$c->flash(filename => $file_url);
return $c->redirect_to('/');
}
}
} else {
my $msg = $c->l('The URL is not valid.');
if (defined($c->param('format')) && $c->param('format') eq 'json') {
return $c->render(
json => {
success => Mojo::JSON->false,
msg => {
filename => $file_url,
msg => $msg
}
}
);
} else {
$c->flash(msg => $msg);
$c->flash(filename => $file_url);
return $c->redirect_to('/');
}
}
}
my $io_scalar = new IO::Scalar \$upload->slurp();
my $mediatype = mimetype($io_scalar);
my ($ext) = ($upload->filename =~ m/.*\.(.*)$/);
my $ip = $c->ip;
my ($msg, $short, $real_short, $token, $thumb, $limit, $created);
# Check file type
if (index($mediatype, 'image/') >= 0) {
# Create directory if needed
mkdir('files', 0700) unless (-d 'files');
if ($c->req->is_limit_exceeded) {
$msg = $c->l('The file exceed the size limit (%1)', $c->req->max_message_size);
if (defined($c->param('format')) && $c->param('format') eq 'json') {
return $c->render(
json => {
success => Mojo::JSON->false,
msg => $msg
}
);
} else {
$c->flash(msg => $msg);
$c->flash(filename => $upload->filename);
return $c->redirect_to('/');
}
}
my $record = Lutim::DB::Image->new(app => $c->app)->select_empty;
if ($record->short) {
# Save file and create record
my $filename = unidecode($upload->filename);
my $ext = ($filename =~ m/([^.]+)$/)[0];
my $path = 'files/'.$record->short.'.'.$ext;
my ($width, $height);
if ($im_loaded && $mediatype ne 'image/svg+xml' && $mediatype !~ m#image/(x-)?xcf# && $mediatype ne 'image/webp') { # ImageMagick don't work in Debian with svg (for now?)
my $im = Image::Magick->new;
$im->BlobToImage($upload->slurp);
# Automatic rotation from EXIF tag
$im->AutoOrient();
# Update the uploaded file with it's auto-rotated clone
my $asset = Mojo::Asset::Memory->new->add_chunk($im->ImageToBlob());
$upload->asset($asset);
# Create the thumbnail
$width = $im->Get('width');
$height = $im->Get('height');
$im->Resize(geometry=>'x85');
$thumb = 'data:'.$mediatype.';base64,';
if ($mediatype eq 'image/gif') {
$thumb .= b64_encode $im->[0]->ImageToBlob();
} else {
$thumb .= b64_encode $im->ImageToBlob();
}
}
unless (defined($keep_exif) && $keep_exif) {
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;
# Use $data in Image::ExifTool object
$et->ExtractInfo($data);
# Remove all metadata
$et->SetNewValue('*', undef);
# Create a temporary IO::Scalar to write into
my $temp;
my $a = new IO::Scalar \$temp;
$et->WriteInfo($data, $a);
# Update the uploaded file with it's no-tags clone
$data = Mojo::Asset::Memory->new->add_chunk($temp);
$upload->asset($data);
}
}
my ($key, $iv);
if ($c->param('crypt') || $c->config('always_encrypt')) {
($upload, $key, $iv) = $c->crypt($upload, $filename);
}
$upload->move_to($path);
$record->path($path)
->filename($filename)
->mediatype($mediatype)
->footprint(digest_file_hex($path, 'SHA-512'))
->enabled(1)
->delete_at_day(($c->param('delete-day') && ($c->param('delete-day') <= $c->max_delay || $c->max_delay == 0)) ? $c->param('delete-day') : $c->max_delay)
->delete_at_first_view(($c->param('first-view'))? 1 : 0)
->created_at(time())
->created_by($ip)
->width($width)
->height($height)
->iv($iv)
->write;
# Log image creation
$c->app->log->info('[CREATION] '.$ip.' pushed '.$filename.' (path: '.$path.')') unless $c->config('quiet_logs');
# Give url to user
$short = $record->short;
$real_short = $short;
if (!defined($record->mod_token)) {
$record->mod_token($c->shortener($c->config->{token_length}))->write;
}
$token = $record->mod_token;
$short .= '/'.$key if (defined($key));
$limit = $record->delete_at_day;
$created = $record->created_at;
} else {
# Houston, we have a problem
$msg = $c->l('There is no more available URL. Retry or contact the administrator. %1', $c->config->{contact});
}
} else {
$msg = $c->l('The file %1 is not an image.', $upload->filename);
}
if (defined($c->param('format')) && $c->param('format') eq 'json') {
if (defined($short)) {
$msg = {
filename => $upload->filename,
short => $short,
real_short => $real_short,
token => $token,
ext => $ext || extensions($mediatype),
thumb => $thumb,
del_at_view => ($c->param('first-view')) ? true : false,
limit => $limit,
created_at => $created
};
} else {
$msg = {
filename => $upload->filename,
msg => $msg
};
}
return $c->render(
json => {
success => (defined($short)) ? Mojo::JSON->true : Mojo::JSON->false,
msg => $msg
}
);
} else {
if ((defined($msg))) {
$c->flash(msg => $msg);
$c->flash(filename => $upload->filename);
return $c->redirect_to('/');
} else {
$c->stash(short => $short) if (defined($short));
$c->stash(real_short => $real_short);
$c->stash(token => $token);
$c->stash(ext => $ext || extensions($mediatype));
$c->stash(thumb => $thumb);
$c->stash(filename => $upload->filename);
return $c->render(
template => 'index',
max_file_size => $c->req->max_message_size
);
}
}
} else {
if (defined($c->param('format')) && $c->param('format') eq 'json') {
return $c->render(
json => {
success => Mojo::JSON->false,
msg => {
filename => $upload->filename,
msg => $c->stash('stop_upload')
}
}
);
} else {
$c->flash(msg => $c->stash('stop_upload'));
$c->flash(filename => $upload->filename);
return $c->redirect_to('/');
}
}
}
sub short {
my $c = shift;
my $short = $c->param('short');
my $touit = $c->param('t');
my $key = $c->param('key');
my $thumb;
$thumb = '' if defined $c->param('thumb');
$thumb = $c->param('width') if defined $c->param('width');
my $dl = (defined($c->param('dl'))) ? 'attachment' : 'inline';
my $image = Lutim::DB::Image->new(app => $c->app, short => $short);
if ($image->enabled && $image->path) {
if($image->delete_at_day && $image->created_at + $image->delete_at_day * 86400 <= time()) {
# Log deletion
$c->app->log->info('[DELETION] someone tried to view '.$image->filename.' but it has been removed by expiration (path: '.$image->path.')') unless $c->config('quiet_logs');
# Delete image
$c->delete_image($image);
# Warn user
$c->flash(
msg => $c->l('Unable to find the image: it has been deleted.')
);
return $c->redirect_to('/');
}
my $test;
if (defined($touit) && $image->mediatype !~ m/svg/) {
$test = 1;
my $short = $image->short;
$short .= '/'.$key if (defined($key));
my ($width, $height) = (340,340);
if ($image->mediatype eq 'image/gif') {
if (defined($image->width) && defined($image->height)) {
($width, $height) = ($image->width, $image->height);
} elsif ($im_loaded) {
my $upload = $c->decrypt($key, $image->path, $image->iv);
my $im = Image::Magick->new;
$im->BlobToImage($upload->slurp);
$width = $im->Get('width');
$height = $im->Get('height');
$image->width($width)
->height($height)
->write;
}
}
return $c->render(
template => 'twitter',
layout => undef,
short => $short,
filename => $image->filename,
mimetype => ($c->req->url->to_abs()->scheme eq 'https') ? $image->mediatype : '',
width => $width,
height => $height
);
} else {
# Delete image if needed
if ($image->delete_at_first_view && $image->counter >= 1) {
# Log deletion
$c->app->log->info('[DELETION] someone made '.$image->filename.' removed (path: '.$image->path.')') unless $c->config('quiet_logs');
# Delete image
$c->delete_image($image);
$c->flash(
msg => $c->l('Unable to find the image: it has been deleted.')
);
return $c->redirect_to('/');
} else {
$test = $c->render_file($im_loaded, $image, $dl, $key, $thumb);
}
}
if ($test != 500) {
# Update counter
$c->on(finish => sub {
# Log access
$c->app->log->info('[VIEW] someone viewed '.$image->filename.' (path: '.$image->path.')') unless $c->config('quiet_logs');
# Update record
unless ($c->config('disable_img_stats')) {
if ($c->config('minion')->{enabled}) {
$c->app->minion->enqueue(accessed => [$image->short, time]);
} else {
$image->accessed(time);
}
}
# Delete image if needed
if ($image->delete_at_first_view) {
# Log deletion
$c->app->log->info('[DELETION] someone made '.$image->filename.' removed (path: '.$image->path.')') unless $c->config('quiet_logs');
# Delete image
$c->delete_image($image);
}
});
} else {
$c->app->log->error('[ERROR] Can\'t render '.$image->short);
}
} elsif ($image->path && !$image->enabled) {
# Log access try
$c->app->log->info('[NOT FOUND] someone tried to view '.$short.' but it does\'nt exist anymore.') unless $c->config('quiet_logs');
# Warn user
$c->flash(
msg => $c->l('Unable to find the image: it has been deleted.')
);
return $c->redirect_to('/');
} else {
# Image never existed
$c->helpers->reply->not_found;
}
}
sub zip {
my $c = shift;
my $imgs = $c->every_param('i');
my $img_nb = scalar(@{$imgs});
my $max_zip = $c->config('max_files_in_zip');
if ($img_nb <= $max_zip) {
my $zip = Archive::Zip->new();
# We HAVE to add a png file at the beginning, otherwise the $zip
# could use the mimetype of an SVG file if it's the first file asked.
$zip->addFile('themes/default/public/img/favicon.png', 'hosted_with_lutim.png');
$zip->addDirectory('images/');
for my $img (@{$imgs}) {
my ($short, $key) = split('/', $img);
if (defined $key) {
$key =~ s/\.[^.]*//;
} else {
$short =~ s/\.[^.]*//;
}
my $image = Lutim::DB::Image->new(app => $c->app, short => $short);
if ($image->enabled && $image->path) {
my $filename = $image->filename;
if($image->delete_at_day && $image->created_at + $image->delete_at_day * 86400 <= time()) {
# Log deletion
$c->app->log->info('[DELETION] someone tried to view '.$image->filename.' but it has been removed by expiration (path: '.$image->path.')') unless $c->config('quiet_logs');
# Delete image
$c->delete_image($image);
# Warn user
$zip->addString(encode('UTF-8', $c->l('Unable to find the image: it has been deleted.')), 'images/'.$filename.'.txt');
next;
}
# Delete image if needed
if ($image->delete_at_first_view && $image->counter >= 1) {
# Log deletion
$c->app->log->info('[DELETION] someone made '.$image->filename.' removed (path: '.$image->path.')') unless $c->config('quiet_logs');
# Delete image
$c->delete_image($image);
$zip->addString(encode('UTF-8', $c->l('Unable to find the image: it has been deleted.')), 'images/'.$filename.'.txt');
next;
} else {
my $expires = ($image->delete_at_day) ? $image->delete_at_day : 360;
my $dt = DateTime->from_epoch( epoch => $expires * 86400 + $image->created_at);
$dt->set_time_zone('GMT');
$expires = $dt->strftime("%a, %d %b %Y %H:%M:%S GMT");
my $path = $image->path;
unless ( -f $path && -r $path ) {
$c->app->log->error("Cannot read file [$path]. error [$!]");
$zip->addString(encode('UTF-8', $c->l('Unable to find the image: it has been deleted.')), 'images/'.$filename.'.txt');
next;
}
if ($key) {
$zip->addString($c->decrypt($key, $path, $image->iv), "images/$filename");
} else {
$zip->addFile($path, "images/$filename");
}
# Log access
$c->app->log->info('[VIEW] someone viewed '.$image->filename.' (path: '.$image->path.')') unless $c->config('quiet_logs');
# Update counter and record
unless ($c->config('disable_img_stats')) {
if ($c->config('minion')->{enabled}) {
$c->app->minion->enqueue(accessed => [$image->short, time]);
} else {
$image->accessed(time);
}
}
}
} elsif ($image->path && !$image->enabled) {
# Log access try
$c->app->log->info('[NOT FOUND] someone tried to view '.$short.' but it does\'nt exist anymore.') unless $c->config('quiet_logs');
# Warn user
$zip->addString(encode('UTF-8', $c->l('Unable to find the image: it has been deleted.')), 'images/'.$image->filename.'.txt');
next;
} else {
$zip->addString(encode('UTF-8', $c->l('Image not found.')), 'images/'.$short.'.txt');
next;
}
}
my ($fh, $zipfile) = Archive::Zip::tempFile();
unless ($zip->writeToFileNamed($zipfile) == AZ_OK) {
$c->flash(
msg => $c->l('Something went wrong when creating the zip file. Try again later or contact the administrator (%1).', $c->config('contact'))
);
return $c->redirect_to('/');
}
$c->res->content->headers->content_type('application/zip;name=images.zip');
$c->res->content->headers->content_disposition('attachment;filename=images.zip');;
my $asset = Mojo::Asset::File->new(path => $zipfile);
$c->res->content->asset($asset);
$c->res->content->headers->content_length($asset->size);
unlink $zipfile;
return $c->rendered(200);
} else {
my $i = -1;
my @urls = ();
my @esc_imgs = map { my $e = $_; $e = url_escape($e); $e =~ s#%2F#/#g; $e } @{$imgs};
while (++$i < $img_nb) {
my $stop = ($i + $max_zip - 1 < $img_nb) ? $i + $max_zip - 1 : $img_nb - 1;
push @urls, $c->url_for('/zip')->to_abs->to_string.'?i='.join('&i=', @esc_imgs[$i..$stop]);
$i = $stop;
}
$c->render(
template => 'zip',
urls => \@urls
);
}
}
sub random {
my $c = shift;
my $imgs = $c->every_param('i');
my $img_nb = scalar(@{$imgs});
if ($img_nb) {
$c->redirect_to($c->prefix.$imgs->[entropy_source->get_int($img_nb)]);
} else {
$c->render_not_found;
}
}
1;

350
lib/Lutim/DB/Image.pm Normal file
View File

@@ -0,0 +1,350 @@
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lutim::DB::Image;
use Mojo::Base -base;
has 'short';
has 'path';
has 'footprint';
has 'enabled';
has 'mediatype';
has 'filename';
has 'counter' => 0;
has 'delete_at_first_view';
has 'delete_at_day';
has 'created_at';
has 'created_by';
has 'last_access_at';
has 'mod_token';
has 'width';
has 'height';
has 'iv';
has 'app';
=head1 NAME
Lutim::DB::Image - DB abstraction layer for Lutim images
=head1 Contributing
When creating a new database accessor, make sure that it provides the following subroutines.
After that, modify this file and modify the C<new> subroutine to allow to use your accessor.
Have a look at Lutim::DB::Image::SQLite's code: it's simple and may be more understandable that this doc.
=head1 Attributes
=over 1
=item B<short> : random string
=item B<path> : string, path to the image, relative to lutim's installation directory
=item B<footprint> : string, sha512 checksum of the image
=item B<enabled> : boolean, is the image accessible?
=item B<mediatype> : string, mimetype of the image
=item B<filename> : string
=item B<counter> : integer
=item B<delete_at_first_view> : boolean
=item B<delete_at_day> : integer, number of days from image upload to deletion
=item B<created_at> : unix timestamp
=item B<created_by> : unix timestamp
=item B<last_access_at> : unix timestamp
=item B<mod_token> : random string
=item B<width> : integer
=item B<height> : integer
=item B<iv> : initialization vector for the file encryption
=item B<app> : a mojolicious object
=back
=head1 Sub routines
=head2 new
=over 1
=item B<Usage> : C<$c = Lutim::DB::Image-E<gt>new(app =E<gt> $self);>
=item B<Arguments> : any of the attribute above
=item B<Purpose> : construct a new db accessor object. If the C<short> attribute is provided, it have to load the informations from the database.
=item B<Returns> : the db accessor object
=item B<Info> : the app argument is used by Lutim::DB::Image to choose which db accessor will be used, you don't need to use it in new(), but you can use it to access helpers or configuration settings in the other subroutines
=back
=cut
sub new {
my $c = shift;
$c = $c->SUPER::new(@_);
if (ref($c) eq 'Lutim::DB::Image') {
my $dbtype = $c->app->config('dbtype');
if ($dbtype eq 'sqlite') {
use Lutim::DB::Image::SQLite;
$c = Lutim::DB::Image::SQLite->new(@_);
} elsif ($dbtype eq 'postgresql') {
use Lutim::DB::Image::Pg;
$c = Lutim::DB::Image::Pg->new(@_);
}
}
return $c;
}
sub to_hash {
my $c = shift;
return {
short => $c->short,
path => $c->path,
footprint => $c->footprint,
enabled => $c->enabled,
mediatype => $c->mediatype,
filename => $c->filename,
counter => $c->counter,
delete_at_first_view => $c->delete_at_first_view,
delete_at_day => $c->delete_at_day,
created_at => $c->created_at,
created_by => $c->created_by,
last_access_at => $c->last_access_at,
mod_token => $c->mod_token,
width => $c->width,
height => $c->height,
height => $c->iv
};
}
=head2 accessed
=over 1
=item B<Usage> : C<$c-E<gt>accessed($time)>
=item B<Arguments> : an unix timestamp
=item B<Purpose> : increments the counter attribute by one, set the last_access_at attribute to $time and update the database
=item B<Returns> : the db accessor object
=back
=head2 count_delete_at_day_endis
=over 1
=item B<Usage> : C<$c-E<gt>count_delete_at_day_endis($delete_at_day, $enabled[, $time])>
=item B<Arguments> : two mandatory parameters: one integer, the delete_at_day attribute, a boolean (0 or 1), the enabled attribute
an optional parameter: an unix timestamp
=item B<Purpose> : count how many images there is with the given delete_at_day attribute, and enabled or disabled, depending on the given enabled attribute
if the optional parameter is given, count only images according to the given mandatory parameters that were created before the timestamp
=item B<Returns> : integer
=back
=head2 count_created_before
=over 1
=item B<Usage> : C<$c-E<gt>count_created_before($time)>
=item B<Arguments> : an unix timestamp
=item B<Purpose> : count how many images have been created before the given timestamp
=item B<Returns> : integer
=back
=head2 select_created_after
=over 1
=item B<Usage> : C<$c-E<gt>select_created_after($time)>
=item B<Arguments> : an unix timestamp
=item B<Purpose> : select images created after the given timestamp
=item B<Returns> : a Mojo::Collection object containing the images created after the given timestamp
=back
=head2 select_empty
=over 1
=item B<Usage> : C<$c-E<gt>select_empty>
=item B<Arguments> : none
=item B<Purpose> : select a ready-to-use empty record
=item B<Returns> : a db accessor object
=back
=head2 write
=over 1
=item B<Usage> : C<$c-E<gt>write>
=item B<Arguments> : none
=item B<Purpose> : create or update a record in the database, with the values of the object's attributes
=item B<Returns> : the db accessor object
=back
=head2 count_short
=over 1
=item B<Usage> : C<$c-E<gt>count_short($short)>
=item B<Arguments> : a random string, unique image identifier in the database
=item B<Purpose> : checks that an identifier isn't already used
=item B<Returns> : integer, number of records having this identifier (should be 0 or 1)
=back
=head2 count_empty
=over 1
=item B<Usage> : C<$c-E<gt>count_empty>
=item B<Arguments> : none
=item B<Purpose> : counts the number of record which path is null
=item B<Returns> : integer
=back
=head2 count_not_empty
=over 1
=item B<Usage> : C<$c-E<gt>count_not_empty>
=item B<Arguments> : none
=item B<Purpose> : counts the number of record which path is not null
=item B<Returns> : integer
=back
=head2 clean_ips_until
=over 1
=item B<Usage> : C<$c-E<gt>clean_ips_until($time)>
=item B<Arguments> : unix timestamp
=item B<Purpose> : remove the image's sender information on images created before the given timestamp
=item B<Returns> : the db accessor object
=back
=head2 get_no_longer_viewed_files
=over 1
=item B<Usage> : C<$c-E<gt>get_no_longer_viewed_files($time)>
=item B<Arguments> : unix timestamp
=item B<Purpose> : get images no longer viewed after the given timestamp
=item B<Returns> : a Mojo::Collection object containing the no longer viewed images as Lutim::DB::Image objects
=back
=head2 get_images_to_clean
=over 1
=item B<Usage> : C<$c-E<gt>get_images_to_clean>
=item B<Arguments> : none
=item B<Purpose> : get images that are expired but not marked as it
=item B<Returns> : a Mojo::Collection object containing the images to clean as Lutim::DB::Image objects
=back
=head2 get_50_oldest
=over 1
=item B<Usage> : C<$c-E<gt>get_50_oldest>
=item B<Arguments> : none
=item B<Purpose> : get the 50 oldest enabled images
=item B<Returns> : a Mojo::Collection object containing the 50 oldest enabled images as Lutim::DB::Image objects
=back
=head2 disable
=over 1
=item B<Usage> : C<$c-E<gt>disable>
=item B<Arguments> : none
=item B<Purpose> : change the attribute C<enabled> to false and update the database record
=item B<Returns> : the db accessor object
=back
=head2 search_created_by
=over 1
=item B<Usage> : C<$c-E<gt>search_created_by($ip)>
=item B<Arguments> : an IP address
=item B<Purpose> : get enabled images that have been uploaded by this IP address (database query: LIKE '$ip%', results may include images uploaded by similar IP addresses)
=item B<Returns> : a Mojo::Collection object containing the matching images as Lutim::DB::Image objects
=back
=cut
1;

252
lib/Lutim/DB/Image/Pg.pm Normal file
View File

@@ -0,0 +1,252 @@
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lutim::DB::Image::Pg;
use Mojo::Base 'Lutim::DB::Image';
use Mojo::Collection 'c';
has 'record' => 0;
sub new {
my $c = shift;
$c = $c->SUPER::new(@_);
$c = $c->_slurp if ($c->short);
return $c;
}
sub accessed {
my $c = shift;
my $time = shift;
my $h = $c->app->pg->db->query('UPDATE lutim SET counter = counter + 1, last_access_at = ? WHERE short = ? RETURNING counter, last_access_at', $time, $c->short)->hashes->first;
$c->counter($h->{counter});
$c->last_access_at($h->{last_access_at});
return $c;
}
sub count_delete_at_day_endis {
my $c = shift;
my $day = shift;
my $enabled = shift;
my $created = shift;
if (defined $created) {
return $c->app->pg->db->query('SELECT count(short) FROM lutim WHERE path IS NOT NULL AND delete_at_day = ? AND enabled = ? AND created_at < ?', $day, $enabled, $created)->hashes->first->{count};
} else {
return $c->app->pg->db->query('SELECT count(short) FROM lutim WHERE path IS NOT NULL AND delete_at_day = ? AND enabled = ?', $day, $enabled)->hashes->first->{count};
}
}
sub count_created_before {
my $c = shift;
my $time = shift;
return $c->app->pg->db->query('SELECT count(short) FROM lutim WHERE path IS NOT NULL AND created_at < ?', $time)->hashes->first->{count};
}
sub select_created_after {
my $c = shift;
my $time = shift;
my @images;
my $records = $c->app->pg->db->query('SELECT * FROM lutim WHERE path IS NOT NULL AND created_at >= ?', $time)->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 select_empty {
my $c = shift;
my $record = $c->app->pg->db->query('SELECT * FROM lutim WHERE path IS NULL')->hashes->shuffle->first;
$c->app->pg->db->query('UPDATE lutim SET path = ? WHERE short = ?', 'used', $record->{short});
$c = $c->_slurp($record);
return $c;
}
sub write {
my $c = shift;
if ($c->record) {
$c->app->pg->db->query('UPDATE lutim SET counter = ?, created_at = ?, created_by = ?, delete_at_day = ?, delete_at_first_view = ?, enabled = ?, filename = ?, footprint = ?, height = ?, last_access_at = ?, mediatype = ?, mod_token = ?, path = ?, short = ?, width = ?, iv = ? WHERE short = ?', $c->counter, $c->created_at, $c->created_by, $c->delete_at_day, $c->delete_at_first_view, $c->enabled, $c->filename, $c->footprint, $c->height, $c->last_access_at, $c->mediatype, $c->mod_token, $c->path, $c->short, $c->width, $c->iv, $c->short);
} else {
$c->app->pg->db->query('INSERT INTO lutim (counter, created_at, created_by, delete_at_day, delete_at_first_view, enabled, filename, footprint, height, last_access_at, mediatype, mod_token, path, short, width, iv) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', $c->counter, $c->created_at, $c->created_by, $c->delete_at_day, $c->delete_at_first_view, $c->enabled, $c->filename, $c->footprint, $c->height, $c->last_access_at, $c->mediatype, $c->mod_token, $c->path, $c->short, $c->width, $c->iv);
$c->record(1);
}
return $c;
}
sub count_short {
my $c = shift;
my $short = shift;
return $c->app->pg->db->query('SELECT count(short) FROM lutim WHERE short = ?', $short)->hashes->first->{count};
}
sub count_empty {
my $c = shift;
return $c->app->pg->db->query('SELECT count(short) FROM lutim WHERE path IS NULL')->hashes->first->{count};
}
sub count_not_empty {
my $c = shift;
return $c->app->pg->db->query('SELECT count(short) FROM lutim WHERE path IS NOT NULL')->hashes->first->{count};
}
sub clean_ips_until {
my $c = shift;
my $time = shift;
$c->app->pg->db->query('UPDATE lutim SET created_by = NULL WHERE path IS NOT NULL AND created_at < ?', $time);
return $c;
}
sub get_no_longer_viewed_files {
my $c = shift;
my $time = shift;
my @images;
my $records = $c->app->pg->db->query('SELECT * FROM lutim WHERE enabled = 1 AND last_access_at < ?', $time)->{hashes};
$records->each(
sub {
my ($e, $num) = @_;
my $i = Lutim::DB::Image->new(app => $c->app);
$i->record(1);
$i->_slurp($e);
push @images, $i;
}
);
return c(@images);
}
sub get_images_to_clean {
my $c = shift;
my @images;
my $records = $c->app->pg->db->query('SELECT * FROM lutim WHERE enabled = 1 AND (delete_at_day * 86400) < (? - created_at) AND delete_at_day != 0', time())->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 get_50_oldest {
my $c = shift;
my @images;
my $records = $c->app->pg->db->query('SELECT * FROM lutim WHERE path IS NOT NULL AND enabled = 1 ORDER BY created_at ASC LIMIT 50')->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 disable {
my $c = shift;
$c->app->pg->db->query('UPDATE lutim SET enabled = 0 WHERE short = ?', $c->short);
$c->enabled(0);
return $c;
}
sub search_created_by {
my $c = shift;
my $ip = shift;
my @images;
my $records = $c->app->pg->db->select('lutim', undef, { enabled => 1, created_by => { -like => $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;
my $image;
if (defined $r) {
$image = $r;
} else {
my $images = $c->app->pg->db->query('SELECT * FROM lutim WHERE short = ?', $c->short)->hashes;
if ($images->size) {
$image = $images->first;
}
}
if ($image) {
$c->short($image->{short});
$c->path($image->{path});
$c->footprint($image->{footprint});
$c->enabled($image->{enabled});
$c->mediatype($image->{mediatype});
$c->filename($image->{filename});
$c->counter($image->{counter});
$c->delete_at_first_view($image->{delete_at_first_view});
$c->delete_at_day($image->{delete_at_day});
$c->created_at($image->{created_at});
$c->created_by($image->{created_by});
$c->last_access_at($image->{last_access_at});
$c->mod_token($image->{mod_token});
$c->width($image->{width});
$c->height($image->{height});
$c->iv($image->{iv});
$c->record(1);
}
return $c;
}
1;

View File

@@ -0,0 +1,253 @@
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lutim::DB::Image::SQLite;
use Mojo::Base 'Lutim::DB::Image';
use Mojo::Collection 'c';
has 'record' => 0;
sub new {
my $c = shift;
$c = $c->SUPER::new(@_);
$c = $c->_slurp if ($c->short);
return $c;
}
sub accessed {
my $c = shift;
my $time = shift;
$c->app->sqlite->db->query('UPDATE lutim SET counter = counter + 1, last_access_at = ? WHERE short = ?', $time, $c->short);
my $h = $c->app->sqlite->db->query('SELECT counter, last_access_at FROM lutim WHERE short = ?', $c->short)->hashes->first;
$c->counter($h->{counter});
$c->last_access_at($h->{last_access_at});
return $c;
}
sub count_delete_at_day_endis {
my $c = shift;
my $day = shift;
my $enabled = shift;
my $created = shift;
if (defined $created) {
return $c->app->sqlite->db->query('SELECT count(short) AS count FROM lutim WHERE path IS NOT NULL AND delete_at_day = ? AND enabled = ? AND created_at < ?', $day, $enabled, $created)->hashes->first->{count};
} else {
return $c->app->sqlite->db->query('SELECT count(short) AS count FROM lutim WHERE path IS NOT NULL AND delete_at_day = ? AND enabled = ?', $day, $enabled)->hashes->first->{count};
}
}
sub count_created_before {
my $c = shift;
my $time = shift;
return $c->app->sqlite->db->query('SELECT count(short) AS count FROM lutim WHERE path IS NOT NULL AND created_at < ?', $time)->hashes->first->{count};
}
sub select_created_after {
my $c = shift;
my $time = shift;
my @images;
my $records = $c->app->sqlite->db->query('SELECT * FROM lutim WHERE path IS NOT NULL AND created_at >= ?', $time)->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 select_empty {
my $c = shift;
my $record = $c->app->sqlite->db->query('SELECT * FROM lutim WHERE path IS NULL')->hashes->shuffle->first;
$c->app->sqlite->db->query('UPDATE lutim SET path = ? WHERE short = ?', 'used', $record->{short});
$c = $c->_slurp($record);
return $c;
}
sub write {
my $c = shift;
if ($c->record) {
$c->app->sqlite->db->query('UPDATE lutim SET counter = ?, created_at = ?, created_by = ?, delete_at_day = ?, delete_at_first_view = ?, enabled = ?, filename = ?, footprint = ?, height = ?, last_access_at = ?, mediatype = ?, mod_token = ?, path = ?, short = ?, width = ?, iv = ? WHERE short = ?', $c->counter, $c->created_at, $c->created_by, $c->delete_at_day, $c->delete_at_first_view, $c->enabled, $c->filename, $c->footprint, $c->height, $c->last_access_at, $c->mediatype, $c->mod_token, $c->path, $c->short, $c->width, $c->iv, $c->short);
} else {
$c->app->sqlite->db->query('INSERT INTO lutim (counter, created_at, created_by, delete_at_day, delete_at_first_view, enabled, filename, footprint, height, last_access_at, mediatype, mod_token, path, short, width, iv) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', $c->counter, $c->created_at, $c->created_by, $c->delete_at_day, $c->delete_at_first_view, $c->enabled, $c->filename, $c->footprint, $c->height, $c->last_access_at, $c->mediatype, $c->mod_token, $c->path, $c->short, $c->width, $c->iv);
$c->record(1);
}
return $c;
}
sub count_short {
my $c = shift;
my $short = shift;
return $c->app->sqlite->db->query('SELECT count(short) AS count FROM lutim WHERE short = ?', $short)->hashes->first->{count};
}
sub count_empty {
my $c = shift;
return $c->app->sqlite->db->query('SELECT count(short) AS count FROM lutim WHERE path IS NULL')->hashes->first->{count};
}
sub count_not_empty {
my $c = shift;
return $c->app->sqlite->db->query('SELECT count(short) AS count FROM lutim WHERE path IS NOT NULL')->hashes->first->{count};
}
sub clean_ips_until {
my $c = shift;
my $time = shift;
$c->app->sqlite->db->query('UPDATE lutim SET created_by = NULL WHERE path IS NOT NULL AND created_at < ?', $time);
return $c;
}
sub get_no_longer_viewed_files {
my $c = shift;
my $time = shift;
my @images;
my $records = $c->app->sqlite->db->query('SELECT * FROM lutim WHERE enabled = 1 AND last_access_at < ?', $time)->{hashes};
$records->each(
sub {
my ($e, $num) = @_;
my $i = Lutim::DB::Image->new(app => $c->app);
$i->record(1);
$i->_slurp($e);
push @images, $i;
}
);
return c(@images);
}
sub get_images_to_clean {
my $c = shift;
my @images;
my $records = $c->app->sqlite->db->query('SELECT * FROM lutim WHERE enabled = 1 AND (delete_at_day * 86400) < (? - created_at) AND delete_at_day != 0', time())->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 get_50_oldest {
my $c = shift;
my @images;
my $records = $c->app->sqlite->db->query('SELECT * FROM lutim WHERE path IS NOT NULL AND enabled = 1 ORDER BY created_at ASC LIMIT 50')->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 disable {
my $c = shift;
$c->app->sqlite->db->query('UPDATE lutim SET enabled = 0 WHERE short = ?', $c->short);
$c->enabled(0);
return $c;
}
sub search_created_by {
my $c = shift;
my $ip = shift;
my @images;
my $records = $c->app->sqlite->db->select('lutim', undef, { enabled => 1, created_by => { -like => $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;
my $image;
if (defined $r) {
$image = $r;
} else {
my $images = $c->app->sqlite->db->query('SELECT * FROM lutim WHERE short = ?', $c->short)->hashes;
if ($images->size) {
$image = $images->first;
}
}
if ($image) {
$c->short($image->{short});
$c->path($image->{path});
$c->footprint($image->{footprint});
$c->enabled($image->{enabled});
$c->mediatype($image->{mediatype});
$c->filename($image->{filename});
$c->counter($image->{counter});
$c->delete_at_first_view($image->{delete_at_first_view});
$c->delete_at_day($image->{delete_at_day});
$c->created_at($image->{created_at});
$c->created_by($image->{created_by});
$c->last_access_at($image->{last_access_at});
$c->mod_token($image->{mod_token});
$c->width($image->{width});
$c->height($image->{height});
$c->iv($image->{iv});
$c->record(1);
}
return $c;
}
1;

View File

@@ -1,93 +0,0 @@
package Lutim::I18N::en;
use Mojo::Base 'Lutim::I18N';
my $inf_body = <<EOF;
<h4>What is Lutim?</h4>
<p>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.</p>
<p>The images you post on Lutim can be stored indefinitely or be deleted at first view or after a delay selected from those proposed.</p>
<h4>How does it work?</h4>
<p>Drag and drop an image in the appropriate area or use the traditional way to send files and Lutim will provide you three URLs. One to view the image, an other to directly download it an a last which you can use in Twitter.</p>
<p>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.</p>
<h4>Is it really free (as in free beer)?</h4>
<p>Yes, it is! On the other side, if you want to support the developer, you can do it via <a href="https://flattr.com/submit/auto?user_id=_SKy_&amp;url=[_1]&amp;title=Lutim&amp;category=software">Flattr</a> or with <a href="bitcoin:1K3n4MXNRSMHk28oTfXEvDunWFthePvd8v?label=lutim">BitCoin</a>.</p>
<h4>Is it really anonymous?</h4>
<p>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!</p>
<p>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).</p>
<p>If the files are deleted if you ask it while posting it, their SHA512 footprint are retained.</p>
<h4>How to report an image?</h4>
<p>Please contact the administrator: [_2]</p>
<h4>How do you pronounce Lutim?</h4>
<p>Juste like you pronounce the French word <a href="https://fr.wikipedia.org/wiki/Lutin">lutin</a> (/ly.tɛ̃/).</p>
<h4>What about the software which provides the service?</h4>
<p>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.</p>
<p>For more details, see the <a href="https://github.com/ldidry/lutim">Github</a> page of the project.</p>
<h4>Main developers</h4>
<ul>
<li>Luc Didry, aka Sky (<a href="http://www.fiat-tux.fr">http://www.fiat-tux.fr</a>), core developer, <a href="https://twitter.com/framasky">\@framasky</a></li>
<li>Dattaz (<a href="http://dattaz.fr">http://dattaz.fr</a>), webapp developer, <a href="https://twitter.com/dat_taz">\@dat_taz</a></li>
</ul>
<h4>Contributors</h4>
<ul>
<li>Jean-Bernard Marcon, aka Goofy (<a href="https://github.com/goofy-bz">https://github.com/goofy-bz</a>)</li>
<li>Jean-Christophe Bach (<a href="https://github.com/jcb">https://github.com/jcb</a>)</li>
<li>Florian Bigard, aka Chocobozzz (<a href="https://github.com/Chocobozzz">https://github.com/Chocobozzz</a>)</li>
</ul>
EOF
our %Lexicon = (
'homepage' => 'Homepage',
'license' => 'License:',
'fork-me' => 'Fork me on Github !',
'share-twitter' => 'Share on Twitter',
'informations' => 'Informations',
'informations-body' => $inf_body,
'view-link' => 'View link',
'download-link' => 'Download link',
'twitter-link' => 'Link for put in a tweet',
'tweet_it' => 'Tweet it!',
'share_it' => 'Share it!',
'delete-link' => 'Deletion link',
'some-bad' => 'Something bad happened',
'delete-first' => 'Delete at first view?',
'delete-day' => 'Delete after 24 hours?',
'upload_image' => 'Send an image',
'image-only' => 'Only images are allowed',
'go' => 'Let\'s go!',
'drag-n-drop' => 'Drag & drop images here',
'or' => '-or-',
'file-browser' => 'Click to open the file browser',
'image_not_found' => 'Unable to find the image: it has been deleted.',
'no_more_short' => 'There is no more available URL. Retry or contact the administrator. [_1]',
'no_valid_file' => 'The file [_1] is not an image.',
'file_too_big' => 'The file exceed the size limit ([_1])',
'no_time_limit' => 'No time limit',
'24_hours' => '24 hours',
'7_days' => '7 days',
'30_days' => '30 days',
'1_year' => 'One year',
'pushed-images' => ' sent images on this instance from beginning.',
'graph-data-once-a-day' => 'The graph\'s datas are not updated in real-time.',
'lutim-stats' => 'Lutim\'s statistics',
'back-to-index' => 'Back to homepage',
'stop_upload' => 'Uploading is currently disabled, please try later or contact the administrator ([_1]).',
'download_error' => 'An error occured while downloading the image.',
'no_valid_url' => 'The URL is not valid.',
'image_url' => 'Image URL',
'upload_image_url' => 'Upload an image with its URL',
'delay_0' => 'no time limit',
'delay_1' => '24 hours',
'delay_days' => '[_1] days',
'delay_365' => '1 year',
'max_delay' => 'Warning! The maximum time limit for an image is [_1] day(s), even if you choose "no time limit".',
'crypt_image' => 'Encrypt the image (Lutim does not keep the key).',
'always_encrypt' => 'The images are encrypted on the server (Lutim does not keep the key).',
'image_deleted' => 'The image [_1] has been successfully deleted',
'invalid_token' => 'The delete token is invalid.',
'already_deleted' => 'The image [_1] has already been deleted.',
'install_as_webapp' => 'Install webapp',
'image_delay_modified' => 'The image\'s delay has been successfully modified',
'image_mod_not_found' => 'Unable to find the image [_1].',
'modify_image_error' => 'Error while trying to modify the image.',
);
1;

View File

@@ -1,93 +0,0 @@
package Lutim::I18N::fr;
use Mojo::Base 'Lutim::I18N';
my $inf_body = <<EOF;
<h4>Quest-ce que Lutim ?</h4>
<p>Lutim est un service gratuit et anonyme dhébergement dimages. Il sagit aussi du nom du logiciel (libre) qui fournit ce service.</p>
<p>Les images déposées sur Lutim peuvent être stockées indéfiniment, ou seffacer dès le premier affichage ou au bout du délai choisi parmi ceux proposés.</p>
<h4>Comment ça marche ?</h4>
<p>Faites glisser des images dans la zone prévue à cet effet ou sélectionnez un fichier de façon classique et Lutim vous fournira troie URLs en retour. Une pour afficher limage, une autre pour la télécharger directement et une dernière utilisable sur Twitter.</p>
<p>Vous pouvez, de façon facultative, demander à ce que la ou les images déposées sur Lutim soient supprimées après leur premier affichage (ou téléchargement) ou au bout d'un délai choisi parmi ceux proposés.</p>
<h4>Cest vraiment gratuit ?</h4>
<p>Oui, ça lest ! Par contre, si vous avez envie de soutenir le développeur, vous pouvez faire un microdon avec <a href="https://flattr.com/submit/auto?user_id=_SKy_&amp;url=[_1]&amp;title=Lutim&amp;category=software">Flattr</a> ou en <a href="bitcoin:1K3n4MXNRSMHk28oTfXEvDunWFthePvd8v?label=lutim">BitCoin</a>.</p>
<h4>Cest vraiment anonyme ?</h4>
<p>Oui, ça lest ! Par contre, pour des raisons légales, votre adresse IP sera enregistrée lorsque vous enverrez une image. Ne vous affolez pas, cest de toute façon normalement le cas de tous les sites sur lesquels vous envoyez des fichiers !</p>
<p>LIP de la personne ayant déposé limage est stockée pendant un délai dépendant de l'administrateur de l'instance (pour l'instance officielle, dont le serveur est en France, c'est un délai d'un an).</p>
<p>Si les fichiers sont bien supprimés si vous en avez exprimé le choix, leur empreinte SHA512 est toutefois conservée.</p>
<h4>Comment peut-on faire pour signaler une image ?</h4>
<p>Veuillez contacter ladministrateur : [_2]</p>
<h4>Comment doit-on prononcer Lutim ?</h4>
<p>Comme on prononce <a href="https://fr.wikipedia.org/wiki/Lutin">lutin</a> !</p>
<h4>Et à propos du logiciel qui fournit le service ?</h4>
<p>Le logiciel Lutim est un <a href="https://fr.wikipedia.org/wiki/Logiciel_libre">logiciel libre</a>, ce qui vous permet de le télécharger et de linstaller sur votre propre serveur. Jetez un coup dœil à l<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL</a> pour voir quels sont vos droits.</p>
<p>Pour plus de détails, consultez la page <a href="https://github.com/ldidry/lutim">Github</a> du projet.</p>
<h4>Développeurs de l'application</h4>
<ul>
<li>Luc Didry, aka Sky (<a href="http://www.fiat-tux.fr">http://www.fiat-tux.fr</a>), développeur principal, <a href="https://twitter.com/framasky">\@framasky</a></li>
<li>Dattaz (<a href="http://dattaz.fr">http://dattaz.fr</a>), développeur de la webapp, <a href="https://twitter.com/dat_taz">\@dat_taz</a></li>
</ul>
<h4>Contributeurs</h4>
<ul>
<li>Jean-Bernard Marcon, aka Goofy (<a href="https://github.com/goofy-bz">https://github.com/goofy-bz</a>)</li>
<li>Jean-Christophe Bach (<a href="https://github.com/jcb">https://github.com/jcb</a>)</li>
<li>Florian Bigard, aka Chocobozzz (<a href="https://github.com/Chocobozzz">https://github.com/Chocobozzz</a>)</li>
</ul>
EOF
our %Lexicon = (
'homepage' => 'Accueil',
'license' => 'Licence :',
'fork-me' => 'Fork me on Github',
'share-twitter' => 'Partager sur Twitter',
'informations' => 'Informations',
'informations-body' => $inf_body,
'view-link' => 'Lien d\'affichage',
'download-link' => 'Lien de téléchargement',
'twitter-link' => 'Lien pour mettre dans un tweet',
'tweet_it' => 'Tweetez !',
'share_it' => 'Partagez !',
'delete-link' => 'Lien de suppression',
'some-bad' => 'Un problème est survenu',
'delete-first' => 'Supprimer au premier accès ?',
'delete-day' => 'Supprimer après 24 heures ?',
'upload_image' => 'Envoyez une image',
'image-only' => 'Seules les images sont acceptées',
'go' => 'Allons-y !',
'drag-n-drop' => 'Déposez vos images ici',
'or' => '-ou-',
'file-browser' => 'Cliquez pour utiliser le navigateur de fichier',
'image_not_found' => 'Impossible de trouver l\'image : elle a été supprimée.',
'no_more_short' => 'Il n\'y a plus d\'URL disponible. Veuillez réessayer ou contactez l\'administrateur. [_1].',
'no_valid_file' => 'Le fichier [_1] n\'est pas une image.',
'file_too_big' => 'Le fichier dépasse la limite de taille ([_1])',
'no_time_limit' => 'Pas de limitation de durée',
'24_hours' => '24 heures',
'7_days' => '7 jours',
'30_days' => '30 jours',
'1_year' => 'Un an',
'pushed-images' => ' images envoyées sur cette instance depuis le début.',
'graph-data-once-a-day' => 'Les données du graphique ne sont pas mises à jour en temps réél.',
'lutim-stats' => 'Statistiques de Lutim',
'back-to-index' => 'Retour à la page d\'accueil',
'stop_upload' => 'L\'envoi d\'images est actuellement désactivé, veuillez réessayer plus tard ou contacter l\'administrateur ([_1]).',
'download_error' => 'Une erreur est survenue lors du téléchargement de l\'image.',
'no_valid_url' => 'l\'URL n\'est pas valide.',
'image_url' => 'URL de l\'image',
'upload_image_url' => 'Déposer une image par son URL',
'delay_0' => 'pas de limitation de durée',
'delay_1' => '24 heures',
'delay_days' => '[_1] jours',
'delay_365' => '1 an',
'max_delay' => 'Attention ! Le délai maximal de rétention d\'une image est de [_1] jour(s), même si vous choisissez « pas de limitation de durée ».',
'crypt_image' => 'Chiffrer l\'image (Lutim ne stocke pas la clé).',
'always_encrypt' => 'Les images sont chiffrées sur le serveur (Lutim ne stocke pas la clé).',
'image_deleted' => 'L\'image [_1] a été supprimée avec succès.',
'invalid_token' => 'Le jeton de suppression est invalide.',
'already_deleted' => 'L\'image [_1] a déjà été supprimée.',
'install_as_webapp' => 'Installer la webapp',
'image_delay_modified' => 'Le délai de l\'image a été modifié avec succès.',
'image_mod_not_found' => 'Impossible de trouver l\'image [_1].',
'modify_image_error' => 'Une erreur est survenue lors de la tentative de modification de l\'image.',
);
1;

View File

@@ -0,0 +1,50 @@
package Lutim::Plugin::Headers;
use Mojo::Base 'Mojolicious::Plugin';
sub register {
my ($self, $app) = @_;
# Assets Cache headers
$app->plugin('StaticCache' => { even_in_dev => 1 });
# Add CSP Header
if (!defined($app->config('csp')) || (defined($app->config('csp')) && $app->config('csp') ne '')) {
my $directives = {
'default-src' => "'none'",
'script-src' => "'self' 'unsafe-eval'",
'style-src' => "'self' 'unsafe-inline'",
'connect-src' => "'self'",
'img-src' => "'self' data:",
'font-src' => "'self'",
'form-action' => "'self'",
'base-uri' => "'self'",
};
my $frame_ancestors = '';
$frame_ancestors = "'none'" if $app->config('x_frame_options') eq 'DENY';
$frame_ancestors = "'self'" if $app->config('x_frame_options') eq 'SAMEORIGIN';
if ($app->config('x_frame_options') =~ m#^ALLOW-FROM#) {
$frame_ancestors = $app->config('x_frame_options');
$frame_ancestors =~ s#ALLOW-FROM +##;
}
$directives->{'frame-ancestors'} = $frame_ancestors if $frame_ancestors;
$app->plugin('CSPHeader',
csp => $app->config('csp'),
directives => $directives
);
}
# Add other headers
$app->hook(
before_dispatch => sub {
my $c = shift;
$c->res->headers->header('X-Frame-Options' => $app->config('x_frame_options')) if $app->config('x_frame_options');
$c->res->headers->header('X-Content-Type-Options' => $app->config('x_content_type_options')) if $app->config('x_content_type_options');
$c->res->headers->header('X-XSS-Protection' => $app->config('x_xss_protection')) if $app->config('x_xss_protection');
}
);
}
1;

336
lib/Lutim/Plugin/Helpers.pm Normal file
View File

@@ -0,0 +1,336 @@
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lutim::Plugin::Helpers;
use Mojo::Base 'Mojolicious::Plugin';
use Mojo::Util qw(quote);
use Mojo::File;
use Crypt::CBC;
use Data::Entropy qw(entropy_source);
use DateTime;
use Mojo::Util qw(decode);
use ISO::639_1;
sub register {
my ($self, $app) = @_;
if ($app->config('dbtype') eq 'postgresql') {
require Mojo::Pg;
$app->plugin('PgURLHelper');
$app->helper(pg => \&_pg);
# Database migration
my $migrations = Mojo::Pg::Migrations->new(pg => $app->pg);
if ($app->mode eq 'development' && $ENV{LUTIM_DEBUG}) {
$migrations->from_file('utilities/migrations/postgresql.sql')->migrate(0)->migrate(3);
} else {
$migrations->from_file('utilities/migrations/postgresql.sql')->migrate(3);
}
} elsif ($app->config('dbtype') eq 'sqlite') {
# SQLite database migration if needed
require Mojo::SQLite;
$app->helper(sqlite => \&_sqlite);
my $sql = Mojo::SQLite->new('sqlite:'.$app->config('db_path'));
my $migrations = $sql->migrations;
if ($app->mode eq 'development' && $ENV{LUTIM_DEBUG}) {
$migrations->from_file('utilities/migrations/sqlite.sql')->migrate(0)->migrate(2);
} else {
$migrations->from_file('utilities/migrations/sqlite.sql')->migrate(2);
}
}
$app->helper(render_file => \&_render_file);
$app->helper(ip => \&_ip);
$app->helper(provisioning => \&_provisioning);
$app->helper(shortener => \&_shortener);
$app->helper(stop_upload => \&_stop_upload);
$app->helper(max_delay => \&_max_delay);
$app->helper(default_delay => \&_default_delay);
$app->helper(is_selected => \&_is_selected);
$app->helper(crypt => \&_crypt);
$app->helper(decrypt => \&_decrypt);
$app->helper(delete_image => \&_delete_image);
$app->helper(iso639_native_name => \&_iso639_native_name);
$app->helper(prefix => \&_prefix);
}
sub _pg {
my $c = shift;
state $pg = Mojo::Pg->new($c->app->pg_url($c->app->config('pgdb')));
return $pg;
}
sub _sqlite {
my $c = shift;
state $sqlite = Mojo::SQLite->new('sqlite:'.$c->app->config('db_path'));
return $sqlite;
}
sub _render_file {
my $c = shift;
my ($im_loaded, $img, $dl, $key, $thumb) = @_;
my ($filename, $path, $iv, $mediatype, $no_cache) = ($img->filename, $img->path, $img->iv, $img->mediatype, $img->delete_at_first_view);
my $expires = ($img->delete_at_day) ? $img->delete_at_day : 360;
my $dt = DateTime->from_epoch( epoch => $expires * 86400 + $img->created_at);
$dt->set_time_zone('GMT');
$expires = $dt->strftime("%a, %d %b %Y %H:%M:%S GMT");
$dl = 'attachment' if ($mediatype =~ m/svg/);
$filename = quote($filename);
unless (-f $path && -r $path) {
$c->app->log->error("Cannot read file [$path]. error [$!]");
$c->flash(
msg => $c->l('Unable to find the image: it has been deleted.')
);
return 500;
}
$mediatype =~ s/x-//;
my $headers = Mojo::Headers->new();
if ($no_cache || defined($thumb)) {
$headers->add('Cache-Control' => 'no-cache, no-store, max-age=0, must-revalidate');
} else {
$headers->add('Expires' => $expires);
}
$headers->add('Content-Type' => $mediatype.';name='.$filename);
$headers->add('Content-Disposition' => $dl.';filename='.$filename);
$c->res->content->headers($headers);
my $cache;
if ($c->config('cache_max_size') != 0 || scalar(@{$c->config('memcached_servers')})) {
$cache = $c->chi('lutim_images_cache')->compute($img->short, undef, sub {
if ($key) {
return {
asset => $c->decrypt($key, $path, $iv),
key => $key
};
} else {
return {
asset => Mojo::File->new($path)->slurp,
};
}
});
if ($key && $key ne $cache->{key}) {
my $tmp = $c->decrypt($key, $path, $iv);
$cache->{asset} = $tmp;
$c->chi('lutim_images_cache')->replace(
$img->short,
{
asset => $tmp,
key => $key
},
);
}
} else {
if ($key) {
$cache = {
asset => $c->decrypt($key, $path, $iv),
};
} else {
$cache = {
asset => Mojo::File->new($path)->slurp,
};
}
}
# Extend expiration time
my $asset = Mojo::Asset::Memory->new;
$asset->add_chunk($cache->{asset});
if (defined $thumb && $im_loaded && $mediatype ne 'image/svg+xml' && $mediatype !~ m#image/(x-)?xcf# && $mediatype ne 'image/webp') { # ImageMagick don't work in Debian with svg (for now?)
my $im = Image::Magick->new;
$im->BlobToImage($asset->slurp);
# Create the thumbnail
if ($thumb eq '') {
$im->Resize(geometry => 'x'.$c->config('thumbnail_size'));
} else {
$im->Resize(geometry => $thumb);
}
# Replace the asset with the thumbnail
$asset = Mojo::Asset::Memory->new->add_chunk($im->ImageToBlob());
}
$c->res->content->asset($asset);
$headers->add('Content-Length' => $asset->size);
return $c->rendered(200);
}
sub _ip {
my $c = shift;
my $ip_only = shift || 0;
my $proxy = $c->req->headers->header('X-Forwarded-For');
my $ip = ($proxy) ? $proxy : $c->tx->remote_address;
my $remote_port = (defined($c->req->headers->header('X-Remote-Port'))) ? $c->req->headers->header('X-Remote-Port') : $c->tx->remote_port;
return ($ip_only) ? $ip : "$ip remote port:$remote_port";
}
sub _provisioning {
my $c = shift;
# Create some short patterns for provisioning
my $img = Lutim::DB::Image->new(app => $c->app);
if ($img->count_empty < $c->app->config('provisioning')) {
for (my $i = 0; $i < $c->app->config('provis_step'); $i++) {
my $short;
do {
$short = $c->shortener($c->app->config('length'));
} while ($img->count_short($short) || $short eq 'about' || $short eq 'stats' || $short eq 'd' || $short eq 'm' || $short eq 'gallery' || $short eq 'zip' || $short eq 'infos');
$img->short($short)
->counter(0)
->enabled(1)
->delete_at_first_view(0)
->delete_at_day(0)
->mod_token($c->shortener($c->app->config('token_length')))
->write;
$img = Lutim::DB::Image->new(app => $c->app);
}
}
}
sub _shortener {
my $c = shift;
my $length = shift;
my @chars = ('a'..'z','A'..'Z','0'..'9');
my $result = '';
foreach (1..$length) {
$result .= $chars[entropy_source->get_int(scalar(@chars))];
}
return $result;
}
sub _stop_upload {
my $c = shift;
if (-f 'stop-upload' || -f 'stop-upload.manual') {
$c->stash(
stop_upload => $c->l('Uploading is currently disabled, please try later or contact the administrator (%1).', $c->app->config('contact'))
);
return 1;
}
return 0;
}
sub _max_delay {
my $c = shift;
return $c->app->config('max_delay') if ($c->app->config('max_delay') >= 0);
warn "max_delay set to a negative value. Default to 0.";
return 0;
}
sub _default_delay {
my $c = shift;
return $c->app->config('default_delay') if ($c->app->config('default_delay') >= 0);
warn "default_delay set to a negative value. Default to 0.";
return 0;
}
sub _is_selected {
my $c = shift;
my $num = shift;
return ($num == $c->default_delay) ? 'selected="selected"' : '';
}
sub _crypt {
my $c = shift;
my $upload = shift;
my $filename = shift;
my $key = $c->shortener($c->config('crypto_key_length'));
my $iv = $c->shortener(8);
my $cipher = Crypt::CBC->new(
-key => $key,
-cipher => 'Blowfish',
-header => 'none',
-iv => $iv
);
$cipher->start('encrypting');
my $crypt_asset = Mojo::Asset::File->new;
$crypt_asset->add_chunk($cipher->crypt($upload->slurp));
$crypt_asset->add_chunk($cipher->finish);
my $crypt_upload = Mojo::Upload->new;
$crypt_upload->filename($filename);
$crypt_upload->asset($crypt_asset);
return ($crypt_upload, $key, $iv);
}
sub _decrypt {
my $c = shift;
my $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
);
$cipher->start('decrypting');
my $decrypt_asset = Mojo::Asset::File->new;
open(my $f, "<",$file) or die "Unable to read encrypted file: $!";
binmode $f;
while (read($f, my $buffer, 1024)) {
$decrypt_asset->add_chunk($cipher->crypt($buffer));
}
$decrypt_asset->add_chunk($cipher->finish) ;
return $decrypt_asset->slurp;
}
sub _delete_image {
my $c = shift;
my $img = shift;
if ($c->config('cache_max_size') != 0 || scalar(@{$c->config('memcached_servers')})) {
$c->chi('lutim_images_cache')->remove($img->short);
}
unlink $img->path or warn "Could not unlink ".$img->path.": $!";
$img->disable();
}
sub _iso639_native_name {
my $c = shift;
return ucfirst(decode 'UTF-8', get_iso639_1(shift)->{nativeName});
}
sub _prefix {
my $c = shift;
my $prefix = $c->url_for('/')->to_abs;
# Forced domain
$prefix->host($c->config('fixed_domain')) if (defined($c->config('fixed_domain')) && $c->config('fixed_domain') ne '');
# Hack for prefix (subdir) handling
$prefix .= '/' unless ($prefix =~ m#/$#);
return $prefix;
}
1;

38
lib/Lutim/Plugin/Lang.pm Normal file
View File

@@ -0,0 +1,38 @@
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lutim::Plugin::Lang;
use Mojo::Base 'Mojolicious::Plugin';
use Mojo::Collection;
use Mojo::File;
sub register {
my ($self, $app) = @_;
$app->helper(available_langs => \&_available_langs);
$app->hook(
before_dispatch => sub {
my $c = shift;
$c->languages($c->cookie('lutim_lang')) if $c->cookie('lutim_lang');
}
);
}
sub _available_langs {
my $c = shift;
state $langs = Mojo::Collection->new(
glob($c->app->home->rel_file('themes/'.$c->config('theme').'/lib/Lutim/I18N/*po')),
glob($c->app->home->rel_file('themes/default/lib/Lutim/I18N/*po'))
)->map(
sub {
Mojo::File->new($_)->basename('.po');
}
)->uniq->sort(
sub {
$c->l($a) cmp $c->l($b)
}
)->to_array;
}
1;

View File

@@ -1,29 +0,0 @@
package LutimModel;
# Create database
use ORLite {
file => 'lutim.db',
unicode => 1,
create => sub {
my $dbh = shift;
$dbh->do(
'CREATE TABLE lutim (
short TEXT PRIMARY KEY,
path TEXT,
footprint TEXT,
enabled INTEGER,
mediatype TEXT,
filename TEXT,
counter INTEGER,
delete_at_first_view INTEGER,
delete_at_day INTEGER,
created_at INTEGER,
created_by TEXT,
last_access_at INTEGER,
mod_token TEXT)'
);
return 1;
}
};
1;

83
lib/Mounter.pm Normal file
View File

@@ -0,0 +1,83 @@
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Mounter;
use Mojo::Base 'Mojolicious';
use Mojo::File;
use FindBin qw($Bin);
use File::Spec qw(catfile);
# This method will run once at server start
sub startup {
my $self = shift;
push @{$self->commands->namespaces}, 'Lutim::Command';
my $cfile = Mojo::File->new($Bin, '..' , 'lutim.conf');
if (defined $ENV{MOJO_CONFIG}) {
$cfile = Mojo::File->new($ENV{MOJO_CONFIG});
unless (-e $cfile->to_abs) {
$cfile = Mojo::File->new($Bin, '..', $ENV{MOJO_CONFIG});
}
}
my $config = $self->plugin('Config' =>
{
file => $cfile,
default => {
provisioning => 100,
provis_step => 5,
length => 8,
always_encrypt => 0,
anti_flood_delay => 5,
max_file_size => 10*1024*1024,
https => 0,
proposed_delays => '0,1,7,30,365',
default_delay => 0,
max_delay => 0,
token_length => 24,
crypto_key_length => 8,
thumbnail_size => 100,
theme => 'default',
dbtype => 'sqlite',
db_path => 'lutim.db',
max_files_in_zip => 15,
prefix => '/',
minion => {
enabled => 0,
dbtype => 'sqlite',
db_path => 'minion.db'
},
cache_max_size => 0,
memcached_servers => [],
quiet_logs => 0,
disable_img_stats => 0,
x_frame_options => 'DENY',
x_content_type_options => 'nosniff',
x_xss_protection => '1; mode=block',
}
}
);
$config->{prefix} = $config->{url_sub_dir} if (defined($config->{url_sub_dir}) && $config->{prefix} eq '/');
$self->app->log->warn('"url_sub_dir" configuration option is deprecated. Use "prefix" instead. "url_sub_dir" will be removed in the future') if (defined($config->{url_sub_dir}));
# Themes handling
shift @{$self->static->paths};
if ($config->{theme} ne 'default') {
my $theme = $self->home->rel_file('themes/'.$config->{theme});
push @{$self->static->paths}, $theme.'/public' if -d $theme.'/public';
}
push @{$self->static->paths}, $self->home->rel_file('themes/default/public');
# Static assets gzipping
$self->plugin('GzipStatic');
# Headers
$self->plugin('Lutim::Plugin::Headers');
# Helpers
$self->plugin('Lutim::Plugin::Helpers');
$self->plugin('Mount' => {$config->{prefix} => File::Spec->catfile($Bin, '..', 'script', 'application')});
}
1;

View File

@@ -7,12 +7,9 @@
hypnotoad => {
# array of IP addresses and ports you want to listen to
listen => ['http://127.0.0.1:8080'],
# user and group you want for Lutim to run with
# be sure that this user/group have rights on the lutim directory
# if you launch lutim from a different user, be sure that this user have the right to su this user/group
# => if current_user is not the user that you sets here and is not root, there's chances that it will fail (see https://github.com/ldidry/lutim/issues/25)
user => 'www-data',
group => 'www-data'
# 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,
},
################
@@ -27,18 +24,23 @@
# mandatory
secrets => ['fdjsofjoihrei'],
# 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
# WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
# in the first version, this option was provisionning with two 'n'. While the option with the typo is still valid, it is deprecated.
# in the next version (0.4), only provisioning with ine 'n' will be accepted
# optional, default is 100
#provisioning => 100,
@@ -49,8 +51,8 @@
# 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, default is @framasky
#tweet_card_via => '@framasky',
# optional, no default
#tweet_card_via => '@foo',
# max image size, in octets
# you can write it 10*1024*1024
@@ -63,7 +65,7 @@
#piwik_img => 'https://piwik.example.org/piwik.php?idsite=1&amp;rec=1',
# if you want to include something in the right of the screen, put it here
# here's an exemple to put the logo of your hoster
# 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">',
@@ -87,6 +89,10 @@
# 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)
@@ -100,6 +106,163 @@
# 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
##########################

File diff suppressed because one or more lines are too long

View File

@@ -1,9 +0,0 @@
.icon-twitter:before { content: '\e800'; } /* '' */
.icon-github-circled:before { content: '\e801'; } /* '' */
.icon-flattr:before { content: '\e802'; } /* '' */
.icon-bitcoin:before { content: '\e803'; } /* '' */
.icon-trash:before { content: '\e804'; } /* '' */
.icon-download:before { content: '\e805'; } /* '' */
.icon-spinner:before { content: '\e806'; } /* '' */
.icon-eye:before { content: '\e807'; } /* '' */

File diff suppressed because one or more lines are too long

View File

@@ -1,9 +0,0 @@
.icon-twitter { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe800;&nbsp;'); }
.icon-github-circled { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe801;&nbsp;'); }
.icon-flattr { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe802;&nbsp;'); }
.icon-bitcoin { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe803;&nbsp;'); }
.icon-trash { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe804;&nbsp;'); }
.icon-download { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe805;&nbsp;'); }
.icon-spinner { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe806;&nbsp;'); }
.icon-eye { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe807;&nbsp;'); }

View File

@@ -1,20 +0,0 @@
[class^="icon-"], [class*=" icon-"] {
font-family: 'fontello';
font-style: normal;
font-weight: normal;
/* fix buttons height */
line-height: 1em;
/* you can be more comfortable with increased icons size */
/* font-size: 120%; */
}
.icon-twitter { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe800;&nbsp;'); }
.icon-github-circled { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe801;&nbsp;'); }
.icon-flattr { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe802;&nbsp;'); }
.icon-bitcoin { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe803;&nbsp;'); }
.icon-trash { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe804;&nbsp;'); }
.icon-download { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe805;&nbsp;'); }
.icon-spinner { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe806;&nbsp;'); }
.icon-eye { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe807;&nbsp;'); }

View File

@@ -1,60 +0,0 @@
@font-face {
font-family: 'fontello';
src: url('../font/fontello.eot?47445522');
src: url('../font/fontello.eot?47445522#iefix') format('embedded-opentype'),
url('../font/fontello.woff?47445522') format('woff'),
url('../font/fontello.ttf?47445522') format('truetype'),
url('../font/fontello.svg?47445522#fontello') format('svg');
font-weight: normal;
font-style: normal;
}
/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */
/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */
/*
@media screen and (-webkit-min-device-pixel-ratio:0) {
@font-face {
font-family: 'fontello';
src: url('../font/fontello.svg?47445522#fontello') format('svg');
}
}
*/
[class^="icon-"]:before, [class*=" icon-"]:before {
font-family: "fontello";
font-style: normal;
font-weight: normal;
speak: none;
display: inline-block;
text-decoration: inherit;
width: 1em;
margin-right: .2em;
text-align: center;
/* opacity: .8; */
/* For safety - reset parent styles, that can break glyph codes*/
font-variant: normal;
text-transform: none;
/* fix buttons height, for twitter bootstrap */
line-height: 1em;
/* Animation center compensation - margins should be symmetric */
/* remove if not needed */
margin-left: .2em;
/* you can be more comfortable with increased icons size */
/* font-size: 120%; */
/* Uncomment for 3D effect */
/* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
}
.icon-twitter:before { content: '\e800'; } /* '' */
.icon-github-circled:before { content: '\e801'; } /* '' */
.icon-flattr:before { content: '\e802'; } /* '' */
.icon-bitcoin:before { content: '\e803'; } /* '' */
.icon-trash:before { content: '\e804'; } /* '' */
.icon-download:before { content: '\e805'; } /* '' */
.icon-spinner:before { content: '\e806'; } /* '' */
.icon-eye:before { content: '\e807'; } /* '' */

View File

@@ -1,6 +0,0 @@
@font-face {
font-family: 'Henny_Penny';
font-style: normal;
font-weight: 400;
src: local('Henny Penny'), local('HennyPenny-Regular'), url(../font/hennypenny.ttf) format('truetype');
}

View File

@@ -1,50 +0,0 @@
@media (max-width: 767px) {
body {
padding-top: 5px;
padding-bottom: 5px;
}
}
@media (min-width: 768px) {
body {
padding-top: 40px;
padding-bottom: 40px;
}
}
.container {
padding: 15px;
margin: 0 auto;
}
.jsonly {
display: none;
}
.thumbnail {
margin-right: 8px;
}
.hennypenny {
font-family: 'Henny_Penny', cursive;
font-size: 42px;
}
.logo {
margin-right: 10px;
}
label.always-encrypt {
display: none;
}
.link_nocol,
.link_nocol:hover{
color: #000000;
text-decoration: none;
}
#install-app img {
height: 22px;
}
#install-app {
display: none;
}

View File

@@ -1,2 +0,0 @@
.morris-hover{position:absolute;z-index:1000;}.morris-hover.morris-default-style{border-radius:10px;padding:6px;color:#666;background:rgba(255, 255, 255, 0.8);border:solid 2px rgba(230, 230, 230, 0.8);font-family:sans-serif;font-size:12px;text-align:center;}.morris-hover.morris-default-style .morris-hover-row-label{font-weight:bold;margin:0.25em 0;}
.morris-hover.morris-default-style .morris-hover-point{white-space:nowrap;margin:0.1em 0;}

Binary file not shown.

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Copyright (C) 2014 by original authors @ fontello.com</metadata>
<defs>
<font id="fontello" horiz-adv-x="1000" >
<font-face font-family="fontello" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
<missing-glyph horiz-adv-x="1000" />
<glyph glyph-name="twitter" unicode="&#xe800;" d="m904 622q-37-54-90-93 0-8 0-23 0-73-21-145t-64-139-103-117-144-82-181-30q-151 0-276 81 19-3 43-3 126 0 224 77-59 2-105 36t-64 89q19-2 34-2 24 0 48 6-63 13-104 62t-41 115v2q38-21 82-23-37 25-59 64t-22 86q0 49 25 91 68-83 164-133t208-55q-5 21-5 41 0 75 53 127t127 53q79 0 132-57 61 12 114 44-20-64-79-100 52 6 104 28z" horiz-adv-x="928.6" />
<glyph glyph-name="github-circled" unicode="&#xe801;" d="m857 350q0-140-82-252t-211-155q-15-3-22 4t-7 17v118q0 54-29 79 32 3 57 10t53 22 45 37 30 58 11 84q0 68-44 115 21 51-5 114-15 5-45-6t-51-25l-21-13q-52 15-107 15t-108-15q-8 6-23 15t-47 22-48 7q-24-63-4-114-44-47-44-115 0-47 12-83t29-59 45-37 52-22 57-10q-22-20-27-58-12-5-25-8t-32-3-36 12-31 35q-11 18-27 29t-28 14l-11 1q-12 0-16-2t-3-7 5-8 7-6l4-3q12-6 24-21t18-29l5-13q8-21 25-34t37-17 39-4 31 2l13 3q0-22 0-50t1-30q0-10-8-17t-22-4q-129 43-211 155t-82 252q0 117 58 215t155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
<glyph glyph-name="flattr" unicode="&#xe802;" d="m0-37l0 514q0 179 85 278t259 99l548 0q-5-5-52-53t-100-101-109-109-95-93-42-37q-15 0-15 16l0 156-48 0q-59 0-94-6t-63-26-39-57-12-96l0-262z m67-117q5 5 53 53t100 101 109 110 95 93 41 36q15 0 15-16l0-156 48 0q116 0 162 36t45 149l0 262 224 223 0-514q0-179-84-278t-260-99l-548 0z" horiz-adv-x="959" />
<glyph glyph-name="bitcoin" unicode="&#xe803;" d="m651 493q10-102-73-144 65-16 98-58t25-119q-4-40-18-70t-36-49-54-33-68-19-81-9v-142h-86v140q-45 0-68 1v-141h-86v142q-10 0-30 1t-31 0h-112l18 102h62q27 0 32 28v225h9q-4 0-9 0v160q-7 38-50 38h-62v92l119-1q35 0 54 1v141h86v-138q45 1 68 1v137h86v-141q44-4 78-13t63-25 46-43 20-64z m-120-304q0 20-8 35t-21 26-32 17-36 10-42 5-38 2-36 0-27-1v-189q5 0 21 0t27 0 29 1 33 2 32 5 31 8 26 11 22 17 14 22 5 29z m-39 265q0 19-7 33t-17 23-27 16-31 9-34 5-33 1-30 0-22-1v-171q3 0 20 0t26 0 27 1 31 3 29 6 27 10 21 15 15 22 5 28z" horiz-adv-x="714.3" />
<glyph glyph-name="trash" unicode="&#xe804;" d="m286 439v-321q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q8 0 13-5t5-13z m143 0v-321q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q8 0 13-5t5-13z m142 0v-321q0-8-5-13t-12-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q7 0 12-5t5-13z m72-404v529h-500v-529q0-12 4-22t8-15 6-5h464q2 0 6 5t8 15 4 22z m-375 601h250l-27 65q-4 5-9 6h-177q-6-1-10-6z m518-18v-36q0-8-5-13t-13-5h-54v-529q0-46-26-80t-63-34h-464q-37 0-63 33t-27 79v531h-53q-8 0-13 5t-5 13v36q0 8 5 13t13 5h172l39 93q9 21 31 35t44 15h178q22 0 44-15t30-35l39-93h173q8 0 13-5t5-13z" horiz-adv-x="785.7" />
<glyph glyph-name="download" unicode="&#xe805;" d="m714 100q0 15-10 25t-25 11-26-11-10-25 10-25 26-11 25 11 10 25z m143 0q0 15-10 25t-26 11-25-11-10-25 10-25 25-11 26 11 10 25z m72 125v-179q0-22-16-37t-38-16h-821q-23 0-38 16t-16 37v179q0 22 16 38t38 16h259l75-76q33-32 76-32t76 32l76 76h259q22 0 38-16t16-38z m-182 318q10-23-8-40l-250-250q-10-10-25-10t-25 10l-250 250q-17 17-8 40 10 21 33 21h143v250q0 15 11 25t25 11h143q14 0 25-11t10-25v-250h143q24 0 33-21z" horiz-adv-x="928.6" />
<glyph glyph-name="spinner" unicode="&#xe806;" d="m469 614v204q129 0 237-61t169-170 62-237h-204q0 72-36 133t-95 96-133 35z" horiz-adv-x="937.5" />
<glyph glyph-name="eye" unicode="&#xe807;" d="m929 314q-85 132-213 197 34-58 34-125 0-104-73-177t-177-73-177 73-73 177q0 67 34 125-128-65-213-197 75-114 187-182t242-68 242 68 187 182z m-402 215q0 11-8 19t-19 7q-70 0-120-50t-50-119q0-12 8-19t19-8 19 8 8 19q0 48 34 82t82 34q11 0 19 8t8 19z m473-215q0-19-11-38-78-129-210-206t-279-77-279 77-210 206q-11 19-11 38t11 39q78 128 210 205t279 78 279-78 210-205q11-20 11-39z" horiz-adv-x="1000" />
</font>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Binary file not shown.

137
public/js/bootstrap.js vendored
View File

@@ -1,137 +0,0 @@
/* ========================================================================
* Bootstrap: alert.js v3.1.1
* http://getbootstrap.com/javascript/#alerts
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */
+function ($) {
'use strict';
// ALERT CLASS DEFINITION
// ======================
var dismiss = '[data-dismiss="alert"]'
var Alert = function (el) {
$(el).on('click', dismiss, this.close)
}
Alert.prototype.close = function (e) {
var $this = $(this)
var selector = $this.attr('data-target')
if (!selector) {
selector = $this.attr('href')
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
}
var $parent = $(selector)
if (e) e.preventDefault()
if (!$parent.length) {
$parent = $this.hasClass('alert') ? $this : $this.parent()
}
$parent.trigger(e = $.Event('close.bs.alert'))
if (e.isDefaultPrevented()) return
$parent.removeClass('in')
function removeElement() {
$parent.trigger('closed.bs.alert').remove()
}
$.support.transition && $parent.hasClass('fade') ?
$parent
.one($.support.transition.end, removeElement)
.emulateTransitionEnd(150) :
removeElement()
}
// ALERT PLUGIN DEFINITION
// =======================
var old = $.fn.alert
$.fn.alert = function (option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.alert')
if (!data) $this.data('bs.alert', (data = new Alert(this)))
if (typeof option == 'string') data[option].call($this)
})
}
$.fn.alert.Constructor = Alert
// ALERT NO CONFLICT
// =================
$.fn.alert.noConflict = function () {
$.fn.alert = old
return this
}
// ALERT DATA-API
// ==============
$(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
}(jQuery);
/* ========================================================================
* Bootstrap: transition.js v3.1.1
* http://getbootstrap.com/javascript/#transitions
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */
+function ($) {
'use strict';
// CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
// ============================================================
function transitionEnd() {
var el = document.createElement('bootstrap')
var transEndEventNames = {
'WebkitTransition' : 'webkitTransitionEnd',
'MozTransition' : 'transitionend',
'OTransition' : 'oTransitionEnd otransitionend',
'transition' : 'transitionend'
}
for (var name in transEndEventNames) {
if (el.style[name] !== undefined) {
return { end: transEndEventNames[name] }
}
}
return false // explicit for ie8 ( ._.)
}
// http://blog.alexmaccaw.com/css-transitions
$.fn.emulateTransitionEnd = function (duration) {
var called = false, $el = this
$(this).one($.support.transition.end, function () { called = true })
var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
setTimeout(callback, duration)
return this
}
$(function () {
$.support.transition = transitionEnd()
})
}(jQuery);

View File

@@ -1,7 +0,0 @@
/*!
* Bootstrap v3.1.1 (http://getbootstrap.com)
* Copyright 2011-2014 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
+function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype.close=function(b){function f(){e.trigger("closed.bs.alert").remove()}var c=a(this),d=c.attr("data-target");d||(d=c.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,""));var e=a(d);b&&b.preventDefault(),e.length||(e=c.hasClass("alert")?c:c.parent()),e.trigger(b=a.Event("close.bs.alert"));if(b.isDefaultPrevented())return;e.removeClass("in"),a.support.transition&&e.hasClass("fade")?e.one(a.support.transition.end,f).emulateTransitionEnd(150):f()};var d=a.fn.alert;a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("bs.alert");e||d.data("bs.alert",e=new c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.alert.Constructor=c,a.fn.alert.noConflict=function(){return a.fn.alert=d,this},a(document).on("click.bs.alert.data-api",b,c.prototype.close)}(jQuery),+function(a){function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(a.style[c]!==undefined)return{end:b[c]};return!1}"use strict",a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one(a.support.transition.end,function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b()})}(jQuery);

File diff suppressed because one or more lines are too long

View File

@@ -1,26 +0,0 @@
$('document').ready(function() {
$('.jsonly').show();
// Are we in a mozilla navigator? (well, are we in a navigator which can handle webapps?)
if (navigator.mozApps !== undefined) {
var installCheck = navigator.mozApps.checkInstalled(manifestUrl);
installCheck.onsuccess = function() {
if(installCheck.result === null) {
var button = $('#install-app');
// Show app install button when app is not installed
button.css('display','inline-block');
button.click(function() {
var request = window.navigator.mozApps.install(manifestUrl);
request.onsuccess = function () {
// Save the App object that is returned
var appRecord = this.result;
button.css('display','none');
};
request.onerror = function () {
// Display the error information from the DOMError object
alert('Install failed, error: ' + this.error.name);
};
});
}
}
}
});

File diff suppressed because one or more lines are too long

11
push-trad-to-zanata.sh Executable file
View File

@@ -0,0 +1,11 @@
#!/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

11
script/application Executable file
View File

@@ -0,0 +1,11 @@
#!/usr/bin/env perl
use strict;
use warnings;
use FindBin;
BEGIN { unshift @INC, "$FindBin::Bin/../lib" }
# Start command line interface for application
require Mojolicious::Commands;
Mojolicious::Commands->start_app('Lutim');

View File

@@ -8,4 +8,4 @@ BEGIN { unshift @INC, "$FindBin::Bin/../lib" }
# Start command line interface for application
require Mojolicious::Commands;
Mojolicious::Commands->start_app('Lutim');
Mojolicious::Commands->start_app('Mounter');

View File

@@ -1,9 +0,0 @@
use Mojo::Base -strict;
use Test::More;
use Test::Mojo;
my $t = Test::Mojo->new('Lutim');
$t->get_ok('/')->status_is(200)->content_like(qr/Mojolicious/i);
done_testing();

4
t/create-pg-testdb.sql Normal file
View File

@@ -0,0 +1,4 @@
CREATE USER lutim WITH PASSWORD 'lutim';
CREATE DATABASE lutimtest OWNER lutim;
CREATE DATABASE lutim_miniontest OWNER lutim;

267
t/postgresql1.conf Normal file
View File

@@ -0,0 +1,267 @@
# 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 => 'John Doe, admin[at]example.com',
# random string used to encrypt cookies
# mandatory
secrets => ['fdjsofjoihrei'],
# 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, default is @framasky
#tweet_card_via => '@framasky',
# max image size, in octets
# you can write it 10*1024*1024
# optional, default is 10485760
max_file_size => 1048576,
# 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&amp;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 => 'test broadcast message',
# 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 => 30,
# 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 => 200,
# 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,
# 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 => 'postgresql',
# 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_db',
host => 'postgres',
user => 'lutim',
pwd => 'lutim_pwd'
},
# 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'
# }
#},
# 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',
##########################
# 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
};

267
t/postgresql2.conf Normal file
View File

@@ -0,0 +1,267 @@
# 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 => 'John Doe, admin[at]example.com',
# random string used to encrypt cookies
# mandatory
secrets => ['fdjsofjoihrei'],
# 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, default is @framasky
#tweet_card_via => '@framasky',
# max image size, in octets
# you can write it 10*1024*1024
# optional, default is 10485760
max_file_size => 1048576,
# 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&amp;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 => 'test broadcast message',
# 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 => 30,
# 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 => 200,
# 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,
# 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 => 'postgresql',
# 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 => 'testpg2.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_db',
host => 'postgres',
user => 'lutim',
pwd => 'lutim_pwd'
},
# use Minion instead of directly increase counters
# need to launch a minion worker service if enabled
# optional, Minion is disabled by default
minion => {
enabled => 1,
# # 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'
# }
},
# 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',
##########################
# 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
};

267
t/postgresql3.conf Normal file
View File

@@ -0,0 +1,267 @@
# 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 => 'John Doe, admin[at]example.com',
# random string used to encrypt cookies
# mandatory
secrets => ['fdjsofjoihrei'],
# 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, default is @framasky
#tweet_card_via => '@framasky',
# max image size, in octets
# you can write it 10*1024*1024
# optional, default is 10485760
max_file_size => 1048576,
# 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&amp;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 => 'test broadcast message',
# 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 => 30,
# 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 => 200,
# 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,
# 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 => 'postgresql',
# 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 => 'testpg3.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_db',
host => 'postgres',
user => 'lutim',
pwd => 'lutim_pwd'
},
# use Minion instead of directly increase counters
# need to launch a minion worker service if enabled
# optional, Minion is disabled by default
minion => {
enabled => 1,
# Which Minion backend to use?
# valid values are sqlite and postgresql (all lowercase)
# mandatory if Minion is enabled, default is sqlite
dbtype => 'postgresql',
# 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 => 'postgres',
user => 'lutim',
pwd => 'lutim_pwd'
}
},
# 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',
##########################
# 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
};

267
t/sqlite1.conf Normal file
View File

@@ -0,0 +1,267 @@
# 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 => 'John Doe, admin[at]example.com',
# random string used to encrypt cookies
# mandatory
secrets => ['fdjsofjoihrei'],
# 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, default is @framasky
#tweet_card_via => '@framasky',
# max image size, in octets
# you can write it 10*1024*1024
# optional, default is 10485760
max_file_size => 1048576,
# 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&amp;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 => 'test broadcast message',
# 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 => 30,
# 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 => 200,
# 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,
# 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 => 'testsqlite1.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'
# }
#},
# 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',
##########################
# 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
};

267
t/sqlite2.conf Normal file
View File

@@ -0,0 +1,267 @@
# 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 => 'John Doe, admin[at]example.com',
# random string used to encrypt cookies
# mandatory
secrets => ['fdjsofjoihrei'],
# 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, default is @framasky
#tweet_card_via => '@framasky',
# max image size, in octets
# you can write it 10*1024*1024
# optional, default is 10485760
max_file_size => 1048576,
# 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&amp;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 => 'test broadcast message',
# 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 => 30,
# 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 => 200,
# 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,
# 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 => 'testsqlite2.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 => 1,
# # 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'
# }
},
# 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',
##########################
# 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
};

267
t/sqlite3.conf Normal file
View File

@@ -0,0 +1,267 @@
# 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 => 'John Doe, admin[at]example.com',
# random string used to encrypt cookies
# mandatory
secrets => ['fdjsofjoihrei'],
# 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, default is @framasky
#tweet_card_via => '@framasky',
# max image size, in octets
# you can write it 10*1024*1024
# optional, default is 10485760
max_file_size => 1048576,
# 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&amp;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 => 'test broadcast message',
# 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 => 30,
# 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 => 200,
# 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,
# 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 => 'testsqlite3.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 => 1,
# Which Minion backend to use?
# valid values are sqlite and postgresql (all lowercase)
# mandatory if Minion is enabled, default is sqlite
dbtype => 'postgresql',
# 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 => 'postgres',
user => 'lutim',
pwd => 'lutim_pwd'
}
},
# 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',
##########################
# 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
};

167
t/test.t Normal file
View File

@@ -0,0 +1,167 @@
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
use Mojo::Base -strict;
use Mojo::File;
use Mojo::JSON qw(true false);
use Mojolicious;
use Test::More;
use Test::Mojo;
use FindBin qw($Bin);
use Digest::file qw(digest_file_hex);
use IO::Uncompress::Unzip qw($UnzipError);
my ($m, $cfile);
BEGIN {
use lib 'lib';
$m = Mojolicious->new;
$cfile = Mojo::File->new($Bin, '..' , 'lutim.conf');
if (defined $ENV{MOJO_CONFIG}) {
$cfile = Mojo::File->new($ENV{MOJO_CONFIG});
unless (-e $cfile->to_abs) {
$cfile = Mojo::File->new($Bin, '..', $ENV{MOJO_CONFIG});
}
}
my $config = $m->plugin('Config' =>
{
file => $cfile->to_abs->to_string,
default => {
provisioning => 100,
provis_step => 5,
length => 8,
always_encrypt => 0,
anti_flood_delay => 5,
max_file_size => 10*1024*1024,
https => 0,
proposed_delays => '0,1,7,30,365',
default_delay => 0,
max_delay => 0,
token_length => 24,
crypto_key_length => 8,
thumbnail_size => 100,
theme => 'default',
dbtype => 'sqlite',
db_path => 'lutim.db',
max_files_in_zip => 15,
prefix => '/',
minion => {
enabled => 0,
dbtype => 'sqlite',
db_path => 'minion.db'
},
cache_max_size => 0,
memcached_servers => [],
quiet_logs => 0,
disable_img_stats => 0,
x_frame_options => 'DENY',
x_content_type_options => 'nosniff',
x_xss_protection => '1; mode=block',
}
}
);
$m->plugin('Lutim::Plugin::Helpers');
}
# Home page
my $t = Test::Mojo->new('Lutim');
$t->get_ok('/')
->status_is(200)
->content_like(qr/Let's Upload That IMage/i)
->header_is('Content-Security-Policy' => "base-uri 'self'; connect-src 'self'; default-src 'none'; font-src 'self'; form-action 'self'; frame-ancestors 'none'; img-src 'self' data:; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'")
->header_is('X-Frame-Options' => 'DENY')
->header_is('X-XSS-Protection' => '1; mode=block')
->header_is('X-Content-Type-Options' => 'nosniff');
# Gzip static assets
$t->get_ok('/css/lutim.css')
->status_is(200)
->header_is(Vary => 'Accept-Encoding');
# Instance settings informations
$t->get_ok('/infos')
->status_is(200)
->json_has('image_magick')
->json_is(
'/always_encrypt' => false,
'/broadcast_message' => 'test broadcast message',
'/contact' => 'John Doe, admin[at]example.com',
'/default_delay' => 30,
'/max_delay' => 200,
'/max_file_size' => 1048576,
'/upload_enabled' => true
);
# Post image
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_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}#);
# Post delete-at-first-view image
my $raw = $t->ua->post('/' => form => { file => { file => $image }, 'first-view' => 1, format => 'json' })->res;
my $short = $raw->json('/msg/short');
$t->get_ok('/'.$short)
->status_is(200);
$t->get_ok('/'.$short)
->status_is(302);
# Get zip file and test it
$t->get_ok('/zip?i='.$short)
->status_is(200)
->header_is('Content-Disposition' => 'attachment;filename=images.zip');
my $zip = $t->ua->get('/zip?i='.$short)->res->body;
my $u = new IO::Uncompress::Unzip \$zip
or die "Cannot open zip file: $UnzipError";
my $status;
my @files = qw(hosted_with_lutim.png images/ images/Lutim.png.txt);
for ($status = 1; $status > 0; $status = $u->nextStream()) {
my $name = $u->getHeaderInfo()->{Name};
is($name, shift(@files));
my $buff;
while (($status = $u->read($buff)) > 0) {
}
last if $status < 0;
}
# Delete image with token
$raw = $t->ua->post('/' => form => { file => { file => $image }, format => 'json' })->res;
my $rshort = $raw->json('/msg/real_short');
my $token = $raw->json('/msg/token');
$t->get_ok('/'.$rshort)
->status_is(200);
$t->get_ok('/d/'.$rshort.'/'.$token, form => { format => 'json' })
->status_is('200')
->json_is(
{
success => true,
msg => 'The image Lutim.png has been successfully deleted'
}
);
$t->get_ok('/'.$rshort)
->status_is(302);
# Needed if we use Minion with sqlite for increasing counters
sleep 8;
# Get image counter
$t->post_ok('/c', form => { short => $rshort, token => $token })
->status_is(200)
->json_is(
{
success => true,
counter => 1,
enabled => false
}
);
done_testing();

View File

@@ -1,5 +0,0 @@
% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:
<div>
<%==l 'informations-body', url_for('/')->to_abs(), config('contact') %>
<%= link_to url_for('index') => ( class => "btn btn-primary btn-lg" ) => begin %><%=l 'back-to-index' %><% end%>
</div>

View File

@@ -1,419 +0,0 @@
% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:
<div class="messages">
% if (config('always_encrypt')) {
<p><%=l 'always_encrypt' %></p>
% }
% if (defined(stash('short'))) {
<div class="alert alert-success">
% if (defined(stash('short'))) {
<img class="pull-left thumbnail" alt="<%= stash('filename') %> thumbnail" src="<%= stash('thumb') %>">
% }
<div>
% # Display image informations
% my $url = url_for('/')->to_abs().stash('short');
<strong><%= stash('filename') %></strong>
&nbsp;&nbsp;&nbsp;<a target="_blank" class="btn btn-default btn-primary btn-xs" href="https://twitter.com/share?url=<%= $url %>?t"><%=l 'tweet_it' %></a>
<ul class="list-unstyled">
% my $delete_url = url_for('delete', {short => stash('real_short'), token => stash('token')})->to_abs();
<li><i class="icon icon-eye" title =" <%= l 'view-link' %>"></i> <%= link_to $url => begin %> <%= $url %> <%= end %></li>
<li><i class="icon icon-download" title =" <%= l 'download-link' %>"></i> <%= link_to $url.'?dl' => begin %> <%= $url.'?dl' %> <%= end %></li>
<li><i class="icon icon-twitter" title =" <%= l 'twitter-link' %>"></i> <%= link_to $url.'?t' => begin %> <%= $url.'?t' %> <%= end %></li>
<li><i class="icon icon-trash" title =" <%= l 'delete-link' %>"></i> <%= link_to $delete_url => begin %> <%= $delete_url %> <%= end %></li>
</ul>
</div>
% # Delay modification form
% my $modify_url = url_for('modify', {short => stash('real_short'), token => stash('token')})->to_abs();
<form class="form" role="form" 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">
% for my $delay (qw/0 1 7 30 365/) {
% my $text = ($delay == 7 || $delay == 30) ? l('delay_days', $delay) : l("delay_$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('delay_1') : l('delay_days', $delay);
<option value="<%= config('max_delay') %>" <%== is_selected(config('max_delay')) %>><%=l('delay_days', config('max_delay')) %></option>
% last;
% }
% }
% } else {
<option value="<%= $delay %>" <%== is_selected($delay) %>><%= $text %></option>
% }
% }
</select>
<div class="checkbox">
<label>
<input type="checkbox" name="first-view"> <%=l 'delete-first' %>
</label>
<label <%== (config('always_encrypt')) ? 'class="always-encrypt"' : '' %>>
<input type="checkbox" name="crypt"> <%=l 'crypt_image' %>
</label>
</div>
<%= submit_button l('go'), class => 'btn btn-sm btn-default btn-primary', id => 'submitbutton' %>
</div>
</form>
</div>
% }
% if (defined(flash('success'))) {
<div class="alert alert-success">
<button type="button" class="close jsonly" data-dismiss="alert" aria-hidden="true">&times;</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">&times;</button>
<strong><%=l 'some-bad' %></strong><br>
<%= flash('filename') %> <%= flash('msg') %>
</div>
% }
</div>
<noscript>
<form class="form" role="form" method="POST" action="<%== url_for('add') %>" enctype="multipart/form-data">
<div class="form-group form-inline">
<select name="delete-day" class="form-control">
% for my $delay (qw/0 1 7 30 365/) {
% my $text = ($delay == 7 || $delay == 30) ? l('delay_days', $delay) : l("delay_$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('delay_1') : l('delay_days', $delay);
<option value="<%= config('max_delay') %>" <%== is_selected(config('max_delay')) %>><%=l('delay_days', config('max_delay')) %></option>
% last;
% }
% }
% } else {
<option value="<%= $delay %>" <%== is_selected($delay) %>><%= $text %></option>
% }
% }
</select>
<div class="checkbox">
<label>
<input type="checkbox" name="first-view"> <%=l 'delete-first' %>
</label>
<label <%== (config('always_encrypt')) ? 'class="always-encrypt"' : '' %>>
<input type="checkbox" name="crypt"> <%=l 'crypt_image' %>
</label>
</div>
</div>
<div class="form-group">
<label for="lutim-file"><%=l 'upload_image' %></label>
<input type="file" name="file" id="lutim-file" accept="image/*">
</div>
<div class="form-group">
<label for="lutim-file-url"><%=l 'upload_image_url' %></label>
<input type="url" name="lutim-file-url" placeholder="<%=l 'image_url' %>">
</div>
<p class="help-block"><%=l 'image-only' %></p>
<%= submit_button l('go'), class => 'btn btn-default btn-primary', id => 'submitbutton' %>
</form>
</noscript>
<!-- D&D Zone-->
<div class="jsonly">
<div class="form-group form-inline">
<select id="delete-day" class="form-control">
% for my $delay (qw/0 1 7 30 365/) {
% my $text = ($delay == 7 || $delay == 30) ? l('delay_days', $delay) : l("delay_$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('delay_1') : l('delay_days', $delay);
<option value="<%= config('max_delay') %>" <%== is_selected(config('max_delay')) %>><%=l('delay_days', config('max_delay')) %></option>
% last;
% }
% }
% } else {
<option value="<%= $delay %>" <%== is_selected($delay) %>><%= $text %></option>
% }
% }
</select>
<div class="checkbox">
<label>
<input type="checkbox" id="first-view"> <%=l 'delete-first' %>
</label>
<label <%== (config('always_encrypt')) ? 'class="always-encrypt"' : '' %>>
<input type="checkbox" id="crypt"> <%=l 'crypt_image' %>
</label>
</div>
</div>
<div id="drag-and-drop-zone" class="uploader">
<div><%=l 'drag-n-drop' %></div>
<div class="or"><%=l 'or' %></div>
<div class="browser">
<label>
<span><%=l 'file-browser' %></span>
<input type="file" name="files[]" multiple="multiple" title='<%=l 'file-browser' %>' accept="image/*">
</label>
</div>
</div>
<p class="help-block"><%=l 'image-only' %></p>
<form class="form-horizontal" role="form" method="POST" action="<%== url_for('add') %>">
<div class="form-group">
<span class="col-sm-3 col-xs-12"><span class="hidden-spin" style="font-size:200%; display:none;" > <i class="icon-spinner animate-spin pull-right"></i></span><label for="lutim-file-url" class="control-label pull-right"><%=l 'upload_image_url' %></label></span>
<div class="col-sm-9 col-xs-12">
<input type="url" name="lutim-file-url" class="form-control" id="lutim-file-url" placeholder="<%=l 'image_url' %>">
</div>
</div>
<a href="#" class="btn btn-default btn-primary pull-right" id="file-url-button"><%=l 'go' %></a>
</form>
</div>
<!-- /D&D Zone -->
%= javascript begin
function link(url, dl, token, modify) {
if (token !== undefined) {
if (modify !== undefined && modify === true) {
return '<%== url_for('index')->to_abs() %>m/'+url+'/'+token;
} else {
url = 'd/'+url+'/'+token;
}
} else if (dl !== '') {
url = url+'?'+dl;
}
return '<a href="<%== url_for('index')->to_abs() %>'+url+'"><%== url_for('index')->to_abs() %>'+url+'</a>';
}
function share(url) {
console.log(url);
new MozActivity({
name: "share",
data: {
type: "url",
number: 1,
url: url
}
});
}
function tw_url(url) {
var btn = '&nbsp;&nbsp;&nbsp;<a target="_blank" class="btn btn-default btn-primary btn-xs" href="https://twitter.com/share?url=<%== url_for('index')->to_abs() %>'+url+'?t"><%=l 'tweet_it' %></a>';
if (navigator.mozSetMessageHandler !== undefined) {
btn = btn+'&nbsp;&nbsp;&nbsp;<a target="_blank" class="btn btn-default btn-primary btn-xs" href="" onclick="share(\'<%== url_for('index')->to_abs() %>'+url+'?t\');return false;"><%=l 'share_it' %></a>';
}
return btn
}
function modify(url, short) {
$.ajax({
url : url,
type : "POST",
data : {
'image_url' : '<%== url_for('index')->to_abs() %>'+short,
'format' : 'json',
'first-view' : ($("#first-view-"+short).prop('checked')) ? 1 : 0,
'delete-day' : $("#day-"+short).val()
},
success: function(data) {
alert(data.msg);
},
error: function() {
alert('<%=l 'modify_image_error' %>');
}
});
}
function build_message(success, msg) {
if(success) {
var thumb = (msg.thumb !== null) ? '<img class="pull-left thumbnail" alt="'+msg.filename+' thumbnail" src="'+msg.thumb+'">' : ''
return '<div class="alert alert-success"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>'
+thumb
+'<div><strong>'
+msg.filename
+'</strong>'
+tw_url(msg.short)
+'<ul class="list-unstyled"><li><i class="icon icon-eye" title="<%=l 'view-link' %>"></i>&nbsp;'
+link(msg.short, '')
+'</li><li><i class="icon icon-download" title="<%=l 'download-link' %>"></i>&nbsp;'
+link(msg.short, 'dl')
+'</li><li><i class="icon icon-twitter" title="<%=l 'twitter-link' %>"></i>&nbsp;'
+link(msg.short, 't')
+'</li><li><i class="icon icon-trash" title="<%=l 'delete-link' %>"></i>&nbsp;'
+link(msg.real_short, '', msg.token)
+'</li></ul><form class="form" 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">'
% for my $delay (qw/0 1 7 30 365/) {
% my $text = ($delay == 7 || $delay == 30) ? l('delay_days', $delay) : l("delay_$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('delay_1') : l('delay_days', $delay);
+'<option value="<%= config('max_delay') %>" <%== is_selected(config('max_delay')) %>><%=l('delay_days', config('max_delay')) %></option>'
% last;
% }
% }
% } else {
+'<option value="<%= $delay %>" <%== is_selected($delay) %>><%= $text %></option>'
% }
% }
+'</select>&nbsp;<div class="checkbox"><label><input id="first-view-'+msg.real_short+'" type="checkbox" name="first-view"> <%=l 'delete-first' %></label>'
+'</div>&nbsp;'
+'<a href="#" onclick="modify(\''+link(msg.real_short, '', msg.token, true)+'\', \''+msg.real_short+'\');return false;" class="btn btn-sm btn-default btn-primary"><%=l 'go' %></a></div></form>'
+'</div>';
} else {
return '<div class="alert alert-danger"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button><strong><%=l 'some-bad' %></strong><br>'
+msg.filename
+"<br>"
+msg.msg
+'</div>';
}
}
function bindddz(firstview, deleteday) {
$('#drag-and-drop-zone').dmUploader({
url: '<%== url_for('add') %>',
dataType: 'json',
allowedTypes: 'image/*',
maxFileSize: <%= $max_file_size %>,
onNewFile: function(id, file){
$(".messages").append('<div id="'+id+'-div">'+file.name+'<br><div class="progress"><div id="'+id+'"class="progress-bar progress-striped active" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%;"><span id="'+id+'-text" class="pull-left" style="padding-left: 10px;"> 0%</span></div></div></div>');
},
onUploadProgress: function(id, percent){
var percentStr = ' '+percent+'%';
$('#'+id).prop('aria-valuenow', percent);
$('#'+id).prop('style', 'width: '+percent+'%;');
$('#'+id+'-text').html(percentStr);
},
onUploadSuccess: function(id, data){
$('#'+id+'-div').remove();
$(".messages").append(build_message(data.success, data.msg));
},
onUploadError: function(id, message){
$(".messages").append(build_message(false, ''));
},
onFileSizeError: function(file){
$(".messages").append(build_message(false, { filename: file.name, msg: '<%= l('file_too_big', $max_file_size) %>'}));
}
});
}
function upload_url() {
var val = $("#lutim-file-url").val();
if (val !== undefined && val !== "") {
$("#lutim-file-url").prop('disabled', 'disabled');
$(".hidden-spin").css('display', 'block');
console.log(val);
$.ajax({
url : '<%== url_for('add') %>',
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) {
$(".messages").append(build_message(data.success, data.msg));
if (data.success) {
$("#lutim-file-url").val('');
}
},
error: function() {
$(".messages").append(build_message(false, ''));
},
complete: function() {
$("#lutim-file-url").prop('disabled', '');
$(".hidden-spin").css('display', 'none');
}
});
} else {
console.log("fhdsjnf");
}
}
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">'+file.name+'<br><div class="progress"><div id="1"class="progress-bar progress-striped active" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%;"><span id="1-text" class="pull-left" style="padding-left: 10px;"> 0%</span></div></div></div>');
// Ajax Submit
$.ajax({
url: '<%== url_for('add') %>',
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').prop('style', 'width: '+percent+'%;');
$('#1-text').html(percentStr);
}, false);
}
return xhrobj;
},
success: function (data, message, xhr){
$('#1-div').remove();
$(".messages").append(build_message(data.success, data.msg));
},
error: function (xhr, status, errMsg){
$(".messages").append(build_message(false, ''));
},
});
}
window.onload = function() {
if (navigator.mozSetMessageHandler !== undefined) {
navigator.mozSetMessageHandler('activity', function handler(activityRequest) {
var activityName = activityRequest.source.name;
if (activityName == 'share') {
activity = activityRequest;
blob = activity.source.data.blobs[0];
fileUpload(blob);
}
});
}
};
$('document').ready(function() {
var firstview = ($("#first-view").prop('checked')) ? 1 : 0;
var deleteday = ($("#delete-day").prop('checked')) ? 1 : 0;
bindddz(firstview, deleteday);
$("#file-url-button").on("click", upload_url);
$('#lutim-file-url').keydown( function(e) {
var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
if(key == 13) {
e.preventDefault();
upload_url();
}
});
});
% end

View File

@@ -1,82 +0,0 @@
% # 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")
% .'&via=framasky'
% .'&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">
% if (current_route 'stats') {
%= asset 'stats.css'
% } elsif (current_route 'about') {
%= asset 'about.css'
% } else {
%= asset 'index.css'
% }
</head>
<body>
<div class="container-fluid">
<div>
% if (defined(config('hosted_by'))) {
<div class="pull-right">
<%== config('hosted_by') %>
</div>
% }
<div>
<div class="pull-left hidden-xs logo">
<img src="<%= url_for('/') %>img/Lutim_small.png" alt="Lutim logo">
</div>
<a class="link_nocol" href="<%= url_for('/') %>" title="<%=l 'homepage' %>"><h1 class="hennypenny">Let's Upload That Image!</h1></a>
<p>
&copy; 2014 <%= link_to 'http://www.fiat-tux.fr' => begin %>Luc Didry<% end %> — 
<%=l 'license' %> <%= link_to 'https://www.gnu.org/licenses/agpl-3.0.html' => begin %>AGPL<% end %> — 
<%= link_to url_for('about') => begin %><%=l 'informations' %><% end %> — 
<%= link_to 'https://github.com/ldidry/lutim' => (title => l 'fork-me') => begin %><i class="lead icon icon-github-circled"></i><% end %> 
<%= link_to $twitter_url => (title => l 'share-twitter') => begin %><i class="lead icon icon-touiteur"></i><% end %> 
<%= link_to 'https://flattr.com/submit/auto?user_id=_SKy_&url='.$url.'&title=Lutim&category=software' => (title => 'Flattr this') => begin %><i class="lead icon icon-flattr"></i><% end %> 
<%= link_to 'bitcoin:1K3n4MXNRSMHk28oTfXEvDunWFthePvd8v?label=lutim' => (title => 'Give Bitcoins') => begin %><i class="lead icon icon-bitcoin"></i><% end %> 
<a class="btn btn-default btn-xs" href="#" id="install-app"><img src="<%= url_for('/') %>img/rocket.png" alt="mozilla rocket logo"> <%=l 'install_as_webapp' %></a>
</p>
</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>
% }
%= javascript begin
var manifestUrl = '<%== url_for('manifest.webapp')->to_abs() %>';
% end
% if (current_route 'stats') {
%= asset 'stats.js'
% } elsif (!(current_route 'about')) {
%= asset 'index.js'
% }
<%= content %>
</div>
% if (defined(config('piwik_img'))) {
<img src="<%== config('piwik_img') %>" style="border:0" alt="" />
% }
</body>
</html>

View File

@@ -1,33 +0,0 @@
{
"name": "Lutim",
"description": "Lets Upload That Image!",
"launch_path": "<%= url_for('/') %>",
"icons": {
"32": "<%= url_for('/img/lutim32.png') %>",
"60": "<%= url_for('/img/lutim60.png') %>",
"90": "<%= url_for('/img/lutim90.png') %>",
"120": "<%= url_for('/img/lutim120.png') %>",
"128": "<%= url_for('/img/lutim128.png') %>",
"256": "<%= url_for('/img/lutim256.png') %>"
},
"developer": {
"name": "Lutim team !",
"url": "https://github.com/ldidry/lutim"
},
"default_locale": "en",
"locales": {
"fr": {
"description": "Envoyons cette image !"
}
},
"activities": {
"share": {
"filters": {
"type": [ "image/*"]
},
"href": "<%= url_for('/') %>",
"disposition": "window"
}
},
"chrome": { "navigation": true }
}

View File

@@ -1,13 +0,0 @@
% # vim:set sts=4 sw=4 ts=4 ft=html.epl expandtab:
<h4><%= $total %><%=l 'pushed-images' %></h4>
<hr>
%= include 'data'
<h4>Uploaded files by days</h4>
<div id="evol-holder"></div>
<hr>
<h4>Evolution of total files</h4>
<div id="total-holder"></div>
<p><small><%=l 'graph-data-once-a-day' %></small></p>
<%= link_to url_for('index') => ( class => "btn btn-primary btn-lg" ) => begin %><%=l 'back-to-index' %><% end%>

View File

@@ -1,18 +0,0 @@
% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:
<!DOCTYPE html>
<html style="height:100%;">
<head>
<title>Lutim</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="utf-8" />
<link rel="icon" type="image/png" href="<%= url_for('/')->to_abs() %>img/favicon.png">
<meta name="twitter:card" content="photo">
<meta name="twitter:site" content="<%= config('tweet_card_via') %>">
<meta name="twitter:image:src" content="<%= url_for('/')->to_abs().$short %>">
</head>
<body style="height: 97%;">
<img style="max-width:100%; max-height:100%;" src="<%= url_for('/').$short %>" alt="<%= $filename %>">
</body>
</html>

View File

@@ -0,0 +1,12 @@
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']
};
1;

View File

@@ -0,0 +1,652 @@
# Lutim language file
# Copyright (C) 2014 Luc Didry
# This file is distributed under the same license as the Lutim package.
#
# Translators:
# ButterflyOfFire <butterflyoffire@protonmail.com>, ٢٠١٨, 2018.
# ButterflyOfFire <butterflyoffire@protonmail.com>, 2018. #zanata
# Luc Didry <luc@framasoft.org>, 2018. #zanata
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"PO-Revision-Date: 2018-07-29 08:17+0000\n"
"Last-Translator: Copied by Zanata <copied-by-zanata@zanata.org>\n"
"Language-Team: Arabic <butterflyoffire+lutim@protonmail.com>\n"
"Language: ar\n"
"Plural-Forms: nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5);\n"
"n%100<=10 ? 3: n%100>=11 ? 4 : 5);\n"
"X-Generator: Zanata 4.5.0\n"
#. (7)
#. (30)
#. ($delay)
#. (config('max_delay')
#: lib/Lutim/Command/cron/stats.pm:147 lib/Lutim/Command/cron/stats.pm:148 lib/Lutim/Command/cron/stats.pm:161 lib/Lutim/Command/cron/stats.pm:162 lib/Lutim/Command/cron/stats.pm:178 lib/Lutim/Command/cron/stats.pm:179 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 أيام"
#. ($total)
#: themes/default/templates/stats.html.ep:2
msgid "%1 sent images on this instance from beginning."
msgstr "تم إرسال %1 صورة على مثيل الخادوم هذا منذ البداية."
#: themes/default/templates/index.html.ep:208
msgid "-or-"
msgstr "-أو-"
#: lib/Lutim.pm:350 lib/Lutim/Command/cron/stats.pm:149 lib/Lutim/Command/cron/stats.pm:163 lib/Lutim/Command/cron/stats.pm:180 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 "سنة واحدة"
#: lib/Lutim.pm:349 lib/Lutim/Command/cron/stats.pm:146 lib/Lutim/Command/cron/stats.pm:160 lib/Lutim/Command/cron/stats.pm:177 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 ساعة"
#: themes/default/templates/partial/myfiles.js.ep:180
msgid ": Error while trying to get the counter."
msgstr ": طرأ هناك خطأ أثناء محاولة إستعادة العداد."
#: themes/default/templates/partial/navbar.html.ep:77
msgid "About"
msgstr "عن البرنامج"
#: lib/Lutim/Command/cron/stats.pm:142 themes/default/templates/raw.html.ep:3
msgid "Active images"
msgstr "الصور النشطة"
#: lib/Lutim/Controller/Image.pm:327
msgid "An error occured while downloading the image."
msgstr "طرأ هناك خطأ أثناء عملية تنزيل الصورة."
#: themes/default/templates/zip.html.ep:2
msgid "Archives download"
msgstr "تنزيل الأرشيف"
#: 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"
msgstr "العودة إلى الصفحة الرئيسية"
#: themes/default/templates/index.html.ep:211 themes/default/templates/index.html.ep:212
msgid "Click to open the file browser"
msgstr "إضغط لفتح مدير الملفات"
#: themes/default/templates/myfiles.html.ep:51
msgid "Close"
msgstr ""
#: themes/default/templates/gallery.html.ep:29
msgid "Close (Esc)"
msgstr "إغلاق (Esc)"
#: themes/default/templates/about.html.ep:30
msgid "Contributors"
msgstr "المساهمون"
#: themes/default/templates/partial/common.js.ep:113 themes/default/templates/partial/common.js.ep:93
msgid "Copied to clipboard"
msgstr ""
#: 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 "أنسخ كافة روابط العرض إلى الحافظة"
#: themes/default/templates/index.html.ep:103 themes/default/templates/index.html.ep:111 themes/default/templates/index.html.ep:18 themes/default/templates/index.html.ep:36 themes/default/templates/index.html.ep:54 themes/default/templates/index.html.ep:87 themes/default/templates/index.html.ep:95 themes/default/templates/myfiles.html.ep:104 themes/default/templates/myfiles.html.ep:68 themes/default/templates/myfiles.html.ep:86 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:142
msgid "Copy to clipboard"
msgstr "أنسخ إلى الحافظة"
#: themes/default/templates/myfiles.html.ep:123
msgid "Counter"
msgstr "العداد"
#: themes/default/templates/stats.html.ep:18
msgid "Delay repartition chart for disabled images"
msgstr ""
#: themes/default/templates/stats.html.ep:15
msgid "Delay repartition chart for enabled images"
msgstr ""
#: 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?"
msgstr "هل تود حذف الصورة مباشرة بعد أول عرض ؟"
#: lib/Lutim/Command/cron/stats.pm:143 themes/default/templates/raw.html.ep:4
msgid "Deleted images"
msgstr "الصور المحذوفة"
#: lib/Lutim/Command/cron/stats.pm:144 themes/default/templates/raw.html.ep:5
msgid "Deleted images in 30 days"
msgstr "الصور المحذوفة منذ 30 يوما"
#: themes/default/templates/index.html.ep:116 themes/default/templates/myfiles.html.ep:127 themes/default/templates/partial/common.js.ep:178 themes/default/templates/partial/common.js.ep:181
msgid "Deletion link"
msgstr "رابط الحذف"
#: themes/default/templates/gallery.html.ep:10
msgid "Download all images"
msgstr "تنزيل كافة الصور"
#: themes/default/templates/index.html.ep:101 themes/default/templates/index.html.ep:99 themes/default/templates/partial/lutim.js.ep:102 themes/default/templates/partial/lutim.js.ep:98
msgid "Download link"
msgstr "رابط التنزيل"
#: themes/default/templates/index.html.ep:28 themes/default/templates/index.html.ep:31 themes/default/templates/myfiles.html.ep:78 themes/default/templates/myfiles.html.ep:81
msgid "Download zip link"
msgstr "رابط التنزيل كحزمة مضغوطة"
#: themes/default/templates/index.html.ep:207
msgid "Drag & drop images here"
msgstr "إسحب ثم القي الصور هنا"
#: 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 ""
"إسحب ثم القي صورة ما على المساحة المخصصة لذلك أو قم باستخدام الأسلوب المعتاد "
"لإرسال الملفات و سيقوم لوتان بعدها بتوفير أربع روابط. رابط لعرض الصورة و "
"آخر لتنزيل الصورة مباشرة و آخر يمكنكم إستخدامه على شبكات التواصل الإجتماعي و "
"أخيرا رابط آخر يمكّنكم من حذف الصورة إن شئتم."
#: themes/default/templates/index.html.ep:168 themes/default/templates/index.html.ep:199
msgid "Encrypt the image (Lutim does not keep the key)."
msgstr "قم بتعمية و تشفير الصورة (لوتان Lutim لا يحتفظ بالمفتاح)."
#: 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 "طرأ هناك خطأ أثناء عملية تعديل الصورة."
#: themes/default/templates/stats.html.ep:10
msgid "Evolution of total files"
msgstr "تطور العدد الإجمالي للملفات"
#: themes/default/templates/myfiles.html.ep:126
msgid "Expires at"
msgstr "تنتهي مدة صلاحيتها في"
#: themes/default/templates/myfiles.html.ep:112
msgid "Export localStorage data"
msgstr ""
#: themes/default/templates/myfiles.html.ep:121
msgid "File name"
msgstr "إسم الملف"
#: themes/default/templates/about.html.ep:24
msgid ""
"For more details, see the <a href=\"https://framagit.org/luc/"
"lutim\">homepage of the project</a>."
msgstr ""
"للمزيد من التفاصيل، قم بزيارة <a href=\"https://framagit.org/luc/"
"lutim\">الصفحة الرئيسة للمشروع</a>."
#: themes/default/templates/partial/navbar.html.ep:80
msgid "Fork me!"
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"
msgstr "رابط المعرض"
#: 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 "إضغط على CTRL+C ثم على مفتاح الإدخال للقيام بنسخ الرابط القصير"
#: themes/default/templates/layouts/default.html.ep:47
msgid "Homepage"
msgstr "الصفحة الرئيسية"
#: themes/default/templates/about.html.ep:20
msgid "How do you pronounce Lutim?"
msgstr "كيف يُنطق Lutim ؟"
#: themes/default/templates/about.html.ep:6
msgid "How does it work?"
msgstr "كيف يشتغل ؟"
#: themes/default/templates/about.html.ep:18
msgid "How to report an image?"
msgstr "كيف يتم الإبلاغ عن صورة ما ؟"
#: 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 ""
"إذا تم حذف الملفات و إن قمت بطلب ذلك أثناء الإرسال سوف نقوم بالإحتفاظ ببصمات "
"SHA512 الخاصة بالصور."
#: themes/default/templates/index.html.ep:181 themes/default/templates/index.html.ep:221
msgid "Image URL"
msgstr "رابط الصورة"
#: lib/Lutim/Command/cron/stats.pm:141 themes/default/templates/raw.html.ep:2
msgid "Image delay"
msgstr "تأجيل الصورة"
#: themes/default/templates/partial/common.js.ep:157
msgid "Image deleted"
msgstr ""
#: lib/Lutim/Controller/Image.pm:753
msgid "Image not found."
msgstr "الصورة غير موجودة."
#: themes/default/templates/myfiles.html.ep:113
msgid "Import localStorage data"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:69
msgid "Informations"
msgstr "معلومات"
#: themes/default/templates/partial/navbar.html.ep:25
msgid "Install webapp"
msgstr "نتصيب برنامج الويب"
#: themes/default/templates/partial/navbar.html.ep:21
msgid "Instance's statistics"
msgstr "إحصائيات مثيل الخادوم"
#: themes/default/templates/about.html.ep:11
msgid "Is it really anonymous?"
msgstr "هل يدعم حقا التخفي ؟"
#: themes/default/templates/about.html.ep:9
msgid "Is it really free (as in free beer)?"
msgstr "هل هو مجاني (كما في عبارة مشروب مجاني) ؟"
#: 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 ""
"يُنطق مِثل الكلمة الفرنسية <a href=\"https://fr.wikipedia.org/wiki/"
"Lutin\">lutin</a> (/ly.tɛ̃/)."
#: themes/default/templates/index.html.ep:171 themes/default/templates/index.html.ep:202
msgid "Keep EXIF tags"
msgstr "الإبقاء على بيانات EXIF"
#: themes/default/templates/partial/navbar.html.ep:43
msgid "Language"
msgstr "اللغة"
#: themes/default/templates/index.html.ep:136 themes/default/templates/index.html.ep:184 themes/default/templates/index.html.ep:224 themes/default/templates/partial/lutim.js.ep:165
msgid "Let's go!"
msgstr "هيا بنا !"
#: themes/default/templates/partial/navbar.html.ep:74
msgid "License:"
msgstr "الرخصة :"
#: themes/default/templates/index.html.ep:107 themes/default/templates/index.html.ep:109 themes/default/templates/partial/lutim.js.ep:112 themes/default/templates/partial/lutim.js.ep:116
msgid "Link for share on social networks"
msgstr "رابط للمشاركة على شبكات التواصل الإجتماعي"
#: themes/default/templates/login.html.ep:8
msgid "Login"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:33
msgid "Logout"
msgstr ""
#: 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 ""
"ليس بمقدور لوتان ضغط العديد من الصور في آن واحد، لذا قام بتقطيع طلبك على شكل "
"عدةروابط."
#: 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 ""
#: themes/default/templates/about.html.ep:25
msgid "Main developers"
msgstr "المطورون الرئيسيون"
#: themes/default/templates/index.html.ep:91 themes/default/templates/index.html.ep:93 themes/default/templates/partial/lutim.js.ep:86 themes/default/templates/partial/lutim.js.ep:89
msgid "Markdown syntax"
msgstr ""
#: themes/default/templates/partial/myfiles.js.ep:149
msgid "Modify expiration delay"
msgstr ""
#: themes/default/templates/myfiles.html.ep:7 themes/default/templates/partial/navbar.html.ep:18
msgid "My images"
msgstr "صوري"
#: themes/default/templates/gallery.html.ep:45
msgid "Next (arrow right)"
msgstr ""
#: themes/default/templates/partial/myfiles.js.ep:105 themes/default/templates/partial/myfiles.js.ep:132
msgid "No limit"
msgstr "غير محدود"
#: themes/default/templates/index.html.ep:183 themes/default/templates/index.html.ep:216
msgid "Only images are allowed"
msgstr "لا يُسمح إلّا بإستضافة الصور"
#: 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 ""
#: 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 ""
#: themes/default/templates/login.html.ep:12
msgid "Password"
msgstr ""
#: themes/default/templates/zip.html.ep:12
msgid "Please click on each URL to download the different zip files."
msgstr ""
#. (config('contact')
#: themes/default/templates/about.html.ep:19
msgid "Please contact the administrator: %1"
msgstr "يرجى الإتصال بالمدير : %1"
#: lib/Lutim/Controller/Authent.pm:36
msgid "Please, check your credentials: unable to authenticate."
msgstr ""
#: themes/default/templates/gallery.html.ep:43
msgid "Previous (arrow left)"
msgstr ""
#: 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"
msgstr ""
#: themes/default/templates/stats.html.ep:22
msgid "Raw stats"
msgstr "الإحصائيات الخامة"
#: themes/default/templates/myfiles.html.ep:52
msgid "Save changes"
msgstr ""
#: themes/default/templates/index.html.ep:176
msgid "Send an image"
msgstr "إرسال صورة"
#: 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 ""
#: 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"
msgstr "طرأ هناك خلل"
#. ($c->config('contact')
#: lib/Lutim/Controller/Image.pm:760
msgid ""
"Something went wrong when creating the zip file. Try again later or contact "
"the administrator (%1)."
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:55
msgid "Support the author"
msgstr "ساند مؤلف البرنامج"
#: themes/default/templates/partial/navbar.html.ep:63
msgid "Support the author on Liberapay"
msgstr "ساند المؤلف عبر ليبراباي"
#: themes/default/templates/partial/navbar.html.ep:60
msgid "Support the author on Tipeee"
msgstr "ساند المؤلف عبر تيبي"
#: 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 ""
#: 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 ""
#: lib/Lutim/Controller/Image.pm:346
msgid "The URL is not valid."
msgstr ""
#: 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 ""
#: themes/default/templates/partial/myfiles.js.ep:32
msgid "The data has been successfully imported."
msgstr ""
#: lib/Lutim/Controller/Image.pm:159 lib/Lutim/Controller/Image.pm:227
msgid "The delete token is invalid."
msgstr ""
#. ($upload->filename)
#: lib/Lutim/Controller/Image.pm:487
msgid "The file %1 is not an image."
msgstr ""
#. ($tx->res->max_message_size)
#. ($c->req->max_message_size)
#. (config('max_file_size')
#: lib/Lutim/Controller/Image.pm:310 lib/Lutim/Controller/Image.pm:379 themes/default/templates/partial/lutim.js.ep:249
msgid "The file exceed the size limit (%1)"
msgstr ""
#: themes/default/templates/stats.html.ep:12
msgid "The graph's datas are not updated in real-time."
msgstr ""
#. ($image->filename)
#: lib/Lutim/Controller/Image.pm:229
msgid "The image %1 has already been deleted."
msgstr ""
#. ($image->filename)
#: lib/Lutim/Controller/Image.pm:238 lib/Lutim/Controller/Image.pm:243
msgid "The image %1 has been successfully deleted"
msgstr ""
#: lib/Lutim/Controller/Image.pm:167
msgid "The image's delay has been successfully modified"
msgstr ""
#: themes/default/templates/index.html.ep:63
msgid "The images are encrypted on the server (Lutim does not keep the key)."
msgstr ""
#: 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 ""
#: themes/default/templates/partial/gallery.js.ep:257
msgid "There is XXXX image(s) in the gallery"
msgstr ""
#. ($c->config->{contact})
#: lib/Lutim/Controller/Image.pm:484
msgid "There is no more available URL. Retry or contact the administrator. %1"
msgstr ""
#: themes/default/templates/gallery.html.ep:30
msgid "Toggle fullscreen"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:8
msgid "Toggle navigation"
msgstr ""
#: lib/Lutim/Command/cron/stats.pm:150 themes/default/templates/raw.html.ep:11
msgid "Total"
msgstr "العدد الإجمالي"
#: themes/default/templates/index.html.ep:78 themes/default/templates/partial/lutim.js.ep:17
msgid "Tweet it!"
msgstr "غرِّد الرابط"
#: themes/default/templates/partial/common.js.ep:110 themes/default/templates/partial/common.js.ep:90
msgid "Unable to copy to clipboard"
msgstr ""
#. ($short)
#: lib/Lutim/Controller/Image.pm:107 lib/Lutim/Controller/Image.pm:201 lib/Lutim/Controller/Image.pm:272
msgid "Unable to find the image %1."
msgstr "تعذر العثور على الصورة %1."
#: lib/Lutim/Controller/Image.pm:573 lib/Lutim/Controller/Image.pm:618 lib/Lutim/Controller/Image.pm:657 lib/Lutim/Controller/Image.pm:700 lib/Lutim/Controller/Image.pm:712 lib/Lutim/Controller/Image.pm:723 lib/Lutim/Controller/Image.pm:750 lib/Lutim/Plugin/Helpers.pm:88
msgid "Unable to find the image: it has been deleted."
msgstr "تعذر العثور على الصورة : لقد تم حذفها."
#: lib/Lutim/Controller/Image.pm:144
msgid "Unable to get counter"
msgstr "تعذر جلب التعداد"
#: themes/default/templates/about.html.ep:17
msgid ""
"Unlike many image sharing services, you don't give us rights on uploaded "
"images."
msgstr ""
#: themes/default/templates/index.html.ep:180 themes/default/templates/index.html.ep:219
msgid "Upload an image with its URL"
msgstr "القيام برفع صورة بواسطة رابطها"
#: themes/default/templates/myfiles.html.ep:125
msgid "Uploaded at"
msgstr "تم رفعها على"
#: themes/default/templates/stats.html.ep:6
msgid "Uploaded files by days"
msgstr "الملفات المستضافة بحسب الأيام"
#. ($c->app->config('contact')
#: lib/Lutim/Plugin/Helpers.pm:221
msgid ""
"Uploading is currently disabled, please try later or contact the "
"administrator (%1)."
msgstr ""
#: themes/default/templates/index.html.ep:83 themes/default/templates/index.html.ep:85 themes/default/templates/myfiles.html.ep:122 themes/default/templates/partial/lutim.js.ep:72 themes/default/templates/partial/lutim.js.ep:76
msgid "View link"
msgstr "عرض الرابط"
#: themes/default/templates/about.html.ep:22
msgid "What about the software which provides the service?"
msgstr ""
#: themes/default/templates/about.html.ep:3
msgid "What is Lutim?"
msgstr "ماذا نقصد بـ Lutim ؟"
#: themes/default/templates/about.html.ep:15
msgid "Who owns rights on images uploaded on Lutim?"
msgstr "من يمتلك حق ملكية الصور المستضافة على Lutim ؟"
#: 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 ""
#: 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 ""
#: themes/default/templates/zip.html.ep:6
msgid "You asked to download a zip archive for too much files."
msgstr ""
#: 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 ""
#: lib/Lutim/Controller/Authent.pm:27
msgid "You have been successfully logged in."
msgstr ""
#: lib/Lutim/Controller/Authent.pm:66 themes/default/templates/logout.html.ep:3
msgid "You have been successfully logged out."
msgstr ""
#: themes/default/templates/gallery.html.ep:31
msgid "Zoom in/out"
msgstr "تكبير/تصغير"
#: themes/default/templates/about.html.ep:27
msgid "and on"
msgstr ""
#: themes/default/templates/about.html.ep:40
msgid "arabic translation"
msgstr "الترجمة إلى العربية"
#: themes/default/templates/about.html.ep:27
msgid "core developer"
msgstr "المطور الرئيسي"
#: lib/Lutim.pm:348 lib/Lutim/Command/cron/stats.pm:145 lib/Lutim/Command/cron/stats.pm:159 lib/Lutim/Command/cron/stats.pm:176 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 ""
#: themes/default/templates/about.html.ep:38
msgid "occitan translation"
msgstr "الترجمة إلى الأوكستانية"
#: themes/default/templates/about.html.ep:27
msgid "on"
msgstr ""
#: themes/default/templates/about.html.ep:39
msgid "paste image to upload ability"
msgstr ""
#: themes/default/templates/about.html.ep:41
msgid "russian translation"
msgstr "الترجمة إلى الروسية"
#: themes/default/templates/about.html.ep:36
msgid "spanish translation"
msgstr "الترجمة إلى الإسبانية"
#: themes/default/templates/about.html.ep:28
msgid "webapp developer"
msgstr "مطور تطبيق الويب"

View File

@@ -0,0 +1,681 @@
# Lutim language file
# Copyright (C) 2014 Luc Didry
# This file is distributed under the same license as the Lutim package.
#
# Translators:
# Translators:
# Thor77 <thor77@thor77.org>, 2015
# Luc Didry <luc@framasoft.org>, 2018. #zanata
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"PO-Revision-Date: 2018-07-29 08:17+0000\n"
"Last-Translator: Copied by Zanata <copied-by-zanata@zanata.org>\n"
"Language-Team: German (http://www.transifex.com/fiat-tux/lutim/language/de/)\n"
"Language: de\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Zanata 4.5.0\n"
#. (7)
#. (30)
#. ($delay)
#. (config('max_delay')
#: lib/Lutim/Command/cron/stats.pm:147 lib/Lutim/Command/cron/stats.pm:148 lib/Lutim/Command/cron/stats.pm:161 lib/Lutim/Command/cron/stats.pm:162 lib/Lutim/Command/cron/stats.pm:178 lib/Lutim/Command/cron/stats.pm:179 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 Tage"
#. ($total)
#: themes/default/templates/stats.html.ep:2
msgid "%1 sent images on this instance from beginning."
msgstr "%1 Bilder wurden bisher über diese Instanz versendet."
#: themes/default/templates/index.html.ep:208
msgid "-or-"
msgstr "-oder-"
#: lib/Lutim.pm:350 lib/Lutim/Command/cron/stats.pm:149 lib/Lutim/Command/cron/stats.pm:163 lib/Lutim/Command/cron/stats.pm:180 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 Jahr"
#: lib/Lutim.pm:349 lib/Lutim/Command/cron/stats.pm:146 lib/Lutim/Command/cron/stats.pm:160 lib/Lutim/Command/cron/stats.pm:177 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 Stunden"
#: themes/default/templates/partial/myfiles.js.ep:180
msgid ": Error while trying to get the counter."
msgstr ":Fehler beim Abrufen des Zählers."
#: themes/default/templates/partial/navbar.html.ep:77
msgid "About"
msgstr ""
#: lib/Lutim/Command/cron/stats.pm:142 themes/default/templates/raw.html.ep:3
msgid "Active images"
msgstr ""
#: lib/Lutim/Controller/Image.pm:327
msgid "An error occured while downloading the image."
msgstr "Beim Herunterladen des Bildes ist ein Fehler aufgetreten."
#: themes/default/templates/zip.html.ep:2
msgid "Archives download"
msgstr ""
#: 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"
msgstr "Zurück zur Hauptseite"
#: themes/default/templates/index.html.ep:211 themes/default/templates/index.html.ep:212
msgid "Click to open the file browser"
msgstr "Klicken um den Dateibrowser zu öffnen"
#: themes/default/templates/myfiles.html.ep:51
msgid "Close"
msgstr "Schließen"
#: themes/default/templates/gallery.html.ep:29
msgid "Close (Esc)"
msgstr "Schließen (Esc)"
#: themes/default/templates/about.html.ep:30
msgid "Contributors"
msgstr "Mitwirkende"
#: themes/default/templates/partial/common.js.ep:113 themes/default/templates/partial/common.js.ep:93
msgid "Copied to clipboard"
msgstr ""
#: 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 "Alle Links zum Anschauen in die Zwischenablage kopieren"
#: themes/default/templates/index.html.ep:103 themes/default/templates/index.html.ep:111 themes/default/templates/index.html.ep:18 themes/default/templates/index.html.ep:36 themes/default/templates/index.html.ep:54 themes/default/templates/index.html.ep:87 themes/default/templates/index.html.ep:95 themes/default/templates/myfiles.html.ep:104 themes/default/templates/myfiles.html.ep:68 themes/default/templates/myfiles.html.ep:86 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:142
msgid "Copy to clipboard"
msgstr "In die Zwischenablage kopieren"
#: themes/default/templates/myfiles.html.ep:123
msgid "Counter"
msgstr "Zähler"
#: themes/default/templates/stats.html.ep:18
msgid "Delay repartition chart for disabled images"
msgstr ""
#: themes/default/templates/stats.html.ep:15
msgid "Delay repartition chart for enabled images"
msgstr ""
#: 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?"
msgstr "Nach erstem Aufruf löschen?"
#: lib/Lutim/Command/cron/stats.pm:143 themes/default/templates/raw.html.ep:4
msgid "Deleted images"
msgstr ""
#: lib/Lutim/Command/cron/stats.pm:144 themes/default/templates/raw.html.ep:5
msgid "Deleted images in 30 days"
msgstr ""
#: themes/default/templates/index.html.ep:116 themes/default/templates/myfiles.html.ep:127 themes/default/templates/partial/common.js.ep:178 themes/default/templates/partial/common.js.ep:181
msgid "Deletion link"
msgstr "Link zum Löschen"
#: themes/default/templates/gallery.html.ep:10
msgid "Download all images"
msgstr "Laden Sie alle Bilder"
#: themes/default/templates/index.html.ep:101 themes/default/templates/index.html.ep:99 themes/default/templates/partial/lutim.js.ep:102 themes/default/templates/partial/lutim.js.ep:98
msgid "Download link"
msgstr "Link zum Herunterladen"
#: themes/default/templates/index.html.ep:28 themes/default/templates/index.html.ep:31 themes/default/templates/myfiles.html.ep:78 themes/default/templates/myfiles.html.ep:81
msgid "Download zip link"
msgstr "Link zum Archivbilder"
#: themes/default/templates/index.html.ep:207
msgid "Drag & drop images here"
msgstr "Bilder hierher ziehen"
#: 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 ""
"Ziehe Bilder in den dafür vorgesehenen Bereich und Lutim wird vier URLs "
"generieren. Eine zum Anschauen, eine zum direkten Herunterladen, eine zum "
"Nutzen in sozialen Netzwerken und eine letzte um das Bild zu löschen."
#: themes/default/templates/index.html.ep:168 themes/default/templates/index.html.ep:199
msgid "Encrypt the image (Lutim does not keep the key)."
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."
#: themes/default/templates/stats.html.ep:10
msgid "Evolution of total files"
msgstr "Entwicklung der Anzahl an Dateien"
#: themes/default/templates/myfiles.html.ep:126
msgid "Expires at"
msgstr "Läuft ab am"
#: themes/default/templates/myfiles.html.ep:112
msgid "Export localStorage data"
msgstr ""
#: themes/default/templates/myfiles.html.ep:121
msgid "File name"
msgstr "Dateiname"
#: themes/default/templates/about.html.ep:24
msgid ""
"For more details, see the <a href=\"https://framagit.org/luc/"
"lutim\">homepage of the project</a>."
msgstr ""
"Besuche für mehr Details die <a href=\"https://framagit.org/luc/"
"lutim\">Homepage des Projekts</a>."
#: themes/default/templates/partial/navbar.html.ep:80
msgid "Fork me!"
msgstr "Fork me!"
#: 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"
msgstr "Link zur Galerie"
#: 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 "Drücke STRG+C und dann Enter um den Kurz-Link zu kopieren."
#: themes/default/templates/layouts/default.html.ep:47
msgid "Homepage"
msgstr "Webseite"
#: themes/default/templates/about.html.ep:20
msgid "How do you pronounce Lutim?"
msgstr "Wie spricht man Lutim aus?"
#: themes/default/templates/about.html.ep:6
msgid "How does it work?"
msgstr "Wie funktionert das?"
#: themes/default/templates/about.html.ep:18
msgid "How to report an image?"
msgstr "Wie kann ich ein Bild melden?"
#: 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 ""
"Wenn du versuchst, ein Bild während dem Hochladen zu löschen, wird die "
"SHA512-Summe des Bildes behalten."
#: themes/default/templates/index.html.ep:181 themes/default/templates/index.html.ep:221
msgid "Image URL"
msgstr "Bild-URL"
#: lib/Lutim/Command/cron/stats.pm:141 themes/default/templates/raw.html.ep:2
msgid "Image delay"
msgstr ""
#: themes/default/templates/partial/common.js.ep:157
msgid "Image deleted"
msgstr ""
#: lib/Lutim/Controller/Image.pm:753
msgid "Image not found."
msgstr "Bild nicht gefunden"
#: themes/default/templates/myfiles.html.ep:113
msgid "Import localStorage data"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:69
msgid "Informations"
msgstr "Informationen"
#: themes/default/templates/partial/navbar.html.ep:25
msgid "Install webapp"
msgstr "Installiere die Webapp"
#: themes/default/templates/partial/navbar.html.ep:21
msgid "Instance's statistics"
msgstr ""
#: themes/default/templates/about.html.ep:11
msgid "Is it really anonymous?"
msgstr "Ist es wirklich anonym?"
#: themes/default/templates/about.html.ep:9
msgid "Is it really free (as in free beer)?"
msgstr "Is es wirklich kostenlos?"
#: 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 ""
"Genauso wie das französische Wort <a href=\"https://fr.wikipedia.org/wiki/"
"Lutin\">lutin</a> (/ly.tɛ̃/)."
#: themes/default/templates/index.html.ep:171 themes/default/templates/index.html.ep:202
msgid "Keep EXIF tags"
msgstr "Behalte EXIF-Daten"
#: themes/default/templates/partial/navbar.html.ep:43
msgid "Language"
msgstr "Sprache"
#: themes/default/templates/index.html.ep:136 themes/default/templates/index.html.ep:184 themes/default/templates/index.html.ep:224 themes/default/templates/partial/lutim.js.ep:165
msgid "Let's go!"
msgstr "Los gehts!"
#: themes/default/templates/partial/navbar.html.ep:74
msgid "License:"
msgstr "Lizenz:"
#: themes/default/templates/index.html.ep:107 themes/default/templates/index.html.ep:109 themes/default/templates/partial/lutim.js.ep:112 themes/default/templates/partial/lutim.js.ep:116
msgid "Link for share on social networks"
msgstr "Links zum teilen auf sozialen Netzwerken"
#: themes/default/templates/login.html.ep:8
msgid "Login"
msgstr "Login"
#: themes/default/templates/partial/navbar.html.ep:33
msgid "Logout"
msgstr "Ausloggen"
#: 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 ""
#: 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 ist ein freier und anonymer Bilder-Upload-Service.\n"
"Es ist auch der Name der freien Software, die diesen Service bietet."
#: themes/default/templates/about.html.ep:25
msgid "Main developers"
msgstr "Haupt-Entwickler"
#: themes/default/templates/index.html.ep:91 themes/default/templates/index.html.ep:93 themes/default/templates/partial/lutim.js.ep:86 themes/default/templates/partial/lutim.js.ep:89
msgid "Markdown syntax"
msgstr "Markdown Syntax"
#: themes/default/templates/partial/myfiles.js.ep:149
msgid "Modify expiration delay"
msgstr ""
#: themes/default/templates/myfiles.html.ep:7 themes/default/templates/partial/navbar.html.ep:18
msgid "My images"
msgstr "Meine Bilder"
#: themes/default/templates/gallery.html.ep:45
msgid "Next (arrow right)"
msgstr ""
#: themes/default/templates/partial/myfiles.js.ep:105 themes/default/templates/partial/myfiles.js.ep:132
msgid "No limit"
msgstr "Keine Begrenzung"
#: themes/default/templates/index.html.ep:183 themes/default/templates/index.html.ep:216
msgid "Only images are allowed"
msgstr "Es sind nur Bilder erlaubt"
#: 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 ""
"Nur die Bilder, die über diesen Browser versendet wurden, werden hier "
"angezeigt. Die Details werden im localStorage gespeichert, wenn du diesen "
"leerst, sind die Details verloren."
#: 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 ""
"Nur der Hochladende (natürlich nur, wenn er vorher auch Rechteinhaber des "
"Bildes war)"
#: themes/default/templates/login.html.ep:12
msgid "Password"
msgstr "Passwort"
#: themes/default/templates/zip.html.ep:12
msgid "Please click on each URL to download the different zip files."
msgstr ""
#. (config('contact')
#: themes/default/templates/about.html.ep:19
msgid "Please contact the administrator: %1"
msgstr "Kontaktiere den Administrator: %1"
#: lib/Lutim/Controller/Authent.pm:36
msgid "Please, check your credentials: unable to authenticate."
msgstr ""
#: themes/default/templates/gallery.html.ep:43
msgid "Previous (arrow left)"
msgstr ""
#: 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"
msgstr ""
#: themes/default/templates/stats.html.ep:22
msgid "Raw stats"
msgstr ""
#: themes/default/templates/myfiles.html.ep:52
msgid "Save changes"
msgstr ""
#: themes/default/templates/index.html.ep:176
msgid "Send an image"
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"
#: 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"
msgstr "Es ist ein Fehler aufgetreten"
#. ($c->config('contact')
#: lib/Lutim/Controller/Image.pm:760
msgid ""
"Something went wrong when creating the zip file. Try again later or contact "
"the administrator (%1)."
msgstr ""
"Es ist ein Fehler aufgetreten. Versuche es erneut oder kontaktiere den "
"Administrator (%1)."
#: themes/default/templates/partial/navbar.html.ep:55
msgid "Support the author"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:63
msgid "Support the author on Liberapay"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:60
msgid "Support the author on Tipeee"
msgstr ""
#: 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 ""
"Die IP-Adresse des Nutzers wird für eine bestimmte Zeit gespeichert. Diese "
"kann der Administrator frei wählen (für die offizielle Instanz, die in "
"Frankreich gehostet ist, liegt diese Zeit bei einem Jahr)"
#: 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 ""
"Lutim ist <a href=\"https://de.wikipedia.org/wiki/Freie_Software\">freie "
"Software</a>, was dir erlaubt sie herunterzuladen und sie auf deinem eigenem "
"Server zu installieren. Schau dir die <a href=\"https://www.gnu.org/licenses/"
"agpl-3.0.html\">AGPL</a> an um deine Recht zu sehen."
#: lib/Lutim/Controller/Image.pm:346
msgid "The URL is not valid."
msgstr "Die URL ist nicht gültig."
#: 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 ""
#: themes/default/templates/partial/myfiles.js.ep:32
msgid "The data has been successfully imported."
msgstr ""
#: lib/Lutim/Controller/Image.pm:159 lib/Lutim/Controller/Image.pm:227
msgid "The delete token is invalid."
msgstr "Das Token zum Löschen ist ungültig."
#. ($upload->filename)
#: lib/Lutim/Controller/Image.pm:487
msgid "The file %1 is not an image."
msgstr "Die Datei %1 ist kein Bild."
#. ($tx->res->max_message_size)
#. ($c->req->max_message_size)
#. (config('max_file_size')
#: lib/Lutim/Controller/Image.pm:310 lib/Lutim/Controller/Image.pm:379 themes/default/templates/partial/lutim.js.ep:249
msgid "The file exceed the size limit (%1)"
msgstr "Die Datei überschreitet die Größenbeschränkung (%1)"
#: themes/default/templates/stats.html.ep:12
msgid "The graph's datas are not updated in real-time."
msgstr "Die Daten des Graphs werden nicht in Echtzeit aktualisiert."
#. ($image->filename)
#: lib/Lutim/Controller/Image.pm:229
msgid "The image %1 has already been deleted."
msgstr "Das Bild %1 wurde schon gelöscht."
#. ($image->filename)
#: lib/Lutim/Controller/Image.pm:238 lib/Lutim/Controller/Image.pm:243
msgid "The image %1 has been successfully deleted"
msgstr "Das Bild %1 wurde erfolgreich gelöscht."
#: lib/Lutim/Controller/Image.pm:167
msgid "The image's delay has been successfully modified"
msgstr "Die Zeit bis zum Löschen des Bildes wurde erfolgreich geändert."
#: themes/default/templates/index.html.ep:63
msgid "The images are encrypted on the server (Lutim does not keep the key)."
msgstr ""
"Die Bilder werden auf dem Server verschlüsselt (Lutim behält den Key nicht)"
#: 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 ""
"Die Bilder, die du auf Lutim hochlädst, können entweder nie, nach dem ersten "
"Aufruf oder nach einer bestimmten Zeit gelöscht werden."
#: themes/default/templates/partial/gallery.js.ep:257
msgid "There is XXXX image(s) in the gallery"
msgstr ""
#. ($c->config->{contact})
#: lib/Lutim/Controller/Image.pm:484
msgid "There is no more available URL. Retry or contact the administrator. %1"
msgstr ""
"Es sind keine URLs mehr verfügbar. Versuche es erneut oder kontaktiere den "
"Administrator. %1"
#: themes/default/templates/gallery.html.ep:30
msgid "Toggle fullscreen"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:8
msgid "Toggle navigation"
msgstr ""
#: lib/Lutim/Command/cron/stats.pm:150 themes/default/templates/raw.html.ep:11
msgid "Total"
msgstr ""
#: themes/default/templates/index.html.ep:78 themes/default/templates/partial/lutim.js.ep:17
msgid "Tweet it!"
msgstr "Twittere es!"
#: themes/default/templates/partial/common.js.ep:110 themes/default/templates/partial/common.js.ep:90
msgid "Unable to copy to clipboard"
msgstr ""
#. ($short)
#: lib/Lutim/Controller/Image.pm:107 lib/Lutim/Controller/Image.pm:201 lib/Lutim/Controller/Image.pm:272
msgid "Unable to find the image %1."
msgstr "Konnte das Bild %1 nicht finden."
#: lib/Lutim/Controller/Image.pm:573 lib/Lutim/Controller/Image.pm:618 lib/Lutim/Controller/Image.pm:657 lib/Lutim/Controller/Image.pm:700 lib/Lutim/Controller/Image.pm:712 lib/Lutim/Controller/Image.pm:723 lib/Lutim/Controller/Image.pm:750 lib/Lutim/Plugin/Helpers.pm:88
msgid "Unable to find the image: it has been deleted."
msgstr "Dieses Bild wurde gelöscht."
#: lib/Lutim/Controller/Image.pm:144
msgid "Unable to get counter"
msgstr "Konnte den Zähler nicht abrufen"
#: themes/default/templates/about.html.ep:17
msgid ""
"Unlike many image sharing services, you don't give us rights on uploaded "
"images."
msgstr ""
"Im Gegensatz zu anderen Bild-Hosting-Diensten, überträgst du uns nicht die "
"Rechte an hochgeladenen Bildern."
#: themes/default/templates/index.html.ep:180 themes/default/templates/index.html.ep:219
msgid "Upload an image with its URL"
msgstr "Lade ein Bild über seine URL hoch"
#: themes/default/templates/myfiles.html.ep:125
msgid "Uploaded at"
msgstr "Hochgeladen am"
#: themes/default/templates/stats.html.ep:6
msgid "Uploaded files by days"
msgstr "Hochgeladene Bilder pro Tag"
#. ($c->app->config('contact')
#: lib/Lutim/Plugin/Helpers.pm:221
msgid ""
"Uploading is currently disabled, please try later or contact the "
"administrator (%1)."
msgstr ""
"Hochladen ist momentan deaktiviert. Versuche es später erneut oder "
"kontaktiere den Administrator (%1)."
#: themes/default/templates/index.html.ep:83 themes/default/templates/index.html.ep:85 themes/default/templates/myfiles.html.ep:122 themes/default/templates/partial/lutim.js.ep:72 themes/default/templates/partial/lutim.js.ep:76
msgid "View link"
msgstr "Link ansehen"
#: themes/default/templates/about.html.ep:22
msgid "What about the software which provides the service?"
msgstr "Welche Software stellt diesen Dienst bereit?"
#: themes/default/templates/about.html.ep:3
msgid "What is Lutim?"
msgstr "Was ist Lutim?"
#: themes/default/templates/about.html.ep:15
msgid "Who owns rights on images uploaded on Lutim?"
msgstr "Wer hat die Rechte an auf Lutim hochgeladenen Bildern?"
#: 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 ""
"Ja, ist es! Auf der anderen Seite wird deine IP-Adresse, wegen rechtlichen "
"Gründen, beim hochladen gespeichert. Keine Panik, das ist normalerweise der "
"Fall für alle Seiten, an die du Dateien sendest!"
#: 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 ""
"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."
#: themes/default/templates/zip.html.ep:6
msgid "You asked to download a zip archive for too much files."
msgstr ""
#: 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 ""
"Du kannst Bilder, die du auf Lutim hochlädst, entweder nach dem ernsten "
"Ansehen (oder Herunterladen) oder nach einem der vorgeschlagenen Zeiten "
"löschen lassen."
#: lib/Lutim/Controller/Authent.pm:27
msgid "You have been successfully logged in."
msgstr ""
#: lib/Lutim/Controller/Authent.pm:66 themes/default/templates/logout.html.ep:3
msgid "You have been successfully logged out."
msgstr ""
#: themes/default/templates/gallery.html.ep:31
msgid "Zoom in/out"
msgstr ""
#: themes/default/templates/about.html.ep:27
msgid "and on"
msgstr "und auf"
#: themes/default/templates/about.html.ep:40
msgid "arabic translation"
msgstr ""
#: themes/default/templates/about.html.ep:27
msgid "core developer"
msgstr "Haupt-Entwickler"
#: lib/Lutim.pm:348 lib/Lutim/Command/cron/stats.pm:145 lib/Lutim/Command/cron/stats.pm:159 lib/Lutim/Command/cron/stats.pm:176 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 "keine Zeit-Begrenzung"
#: themes/default/templates/about.html.ep:38
msgid "occitan translation"
msgstr "okzitanisch Übersetzung"
#: themes/default/templates/about.html.ep:27
msgid "on"
msgstr "auf"
#: themes/default/templates/about.html.ep:39
msgid "paste image to upload ability"
msgstr ""
#: themes/default/templates/about.html.ep:41
msgid "russian translation"
msgstr "russische Übersetzung"
#: themes/default/templates/about.html.ep:36
msgid "spanish translation"
msgstr "spanische Übersetzung"
#: themes/default/templates/about.html.ep:28
msgid "webapp developer"
msgstr "Webapp-Entwickler"

View File

@@ -0,0 +1,677 @@
# Luc Didry <luc@framasoft.org>, 2018. #zanata
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"PO-Revision-Date: 2018-07-29 08:17+0000\n"
"Last-Translator: Copied by Zanata <copied-by-zanata@zanata.org>\n"
"Language-Team: English\n"
"Language: en\n"
"X-Generator: Zanata 4.5.0\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#. (7)
#. (30)
#. ($delay)
#. (config('max_delay')
#: lib/Lutim/Command/cron/stats.pm:147 lib/Lutim/Command/cron/stats.pm:148 lib/Lutim/Command/cron/stats.pm:161 lib/Lutim/Command/cron/stats.pm:162 lib/Lutim/Command/cron/stats.pm:178 lib/Lutim/Command/cron/stats.pm:179 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 days"
#. ($total)
#: themes/default/templates/stats.html.ep:2
msgid "%1 sent images on this instance from beginning."
msgstr "%1 sent images on this instance from beginning."
#: themes/default/templates/index.html.ep:208
msgid "-or-"
msgstr "-or-"
#: lib/Lutim.pm:350 lib/Lutim/Command/cron/stats.pm:149 lib/Lutim/Command/cron/stats.pm:163 lib/Lutim/Command/cron/stats.pm:180 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 year"
#: lib/Lutim.pm:349 lib/Lutim/Command/cron/stats.pm:146 lib/Lutim/Command/cron/stats.pm:160 lib/Lutim/Command/cron/stats.pm:177 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 hours"
#: themes/default/templates/partial/myfiles.js.ep:180
msgid ": Error while trying to get the counter."
msgstr ": Error while trying to get the counter."
#: themes/default/templates/partial/navbar.html.ep:77
msgid "About"
msgstr "About"
#: lib/Lutim/Command/cron/stats.pm:142 themes/default/templates/raw.html.ep:3
msgid "Active images"
msgstr "Active images"
#: lib/Lutim/Controller/Image.pm:327
msgid "An error occured while downloading the image."
msgstr "An error occured while downloading the image."
#: themes/default/templates/zip.html.ep:2
msgid "Archives download"
msgstr "Archives download"
#: 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"
msgstr "Back to homepage"
#: themes/default/templates/index.html.ep:211 themes/default/templates/index.html.ep:212
msgid "Click to open the file browser"
msgstr "Click to open the file browser"
#: themes/default/templates/myfiles.html.ep:51
msgid "Close"
msgstr "Close"
#: themes/default/templates/gallery.html.ep:29
msgid "Close (Esc)"
msgstr "Close (Esc)"
#: themes/default/templates/about.html.ep:30
msgid "Contributors"
msgstr "Contributors"
#: themes/default/templates/partial/common.js.ep:113 themes/default/templates/partial/common.js.ep:93
msgid "Copied to clipboard"
msgstr "Copied to clipboard"
#: 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 "Copy all view links to clipboard"
#: themes/default/templates/index.html.ep:103 themes/default/templates/index.html.ep:111 themes/default/templates/index.html.ep:18 themes/default/templates/index.html.ep:36 themes/default/templates/index.html.ep:54 themes/default/templates/index.html.ep:87 themes/default/templates/index.html.ep:95 themes/default/templates/myfiles.html.ep:104 themes/default/templates/myfiles.html.ep:68 themes/default/templates/myfiles.html.ep:86 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:142
msgid "Copy to clipboard"
msgstr "Copy to clipboard"
#: themes/default/templates/myfiles.html.ep:123
msgid "Counter"
msgstr "Counter"
#: themes/default/templates/stats.html.ep:18
msgid "Delay repartition chart for disabled images"
msgstr "Delay repartition chart for disabled images"
#: themes/default/templates/stats.html.ep:15
msgid "Delay repartition chart for enabled images"
msgstr "Delay repartition chart for enabled images"
#: 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?"
msgstr "Delete at first view?"
#: lib/Lutim/Command/cron/stats.pm:143 themes/default/templates/raw.html.ep:4
msgid "Deleted images"
msgstr "Deleted images"
#: lib/Lutim/Command/cron/stats.pm:144 themes/default/templates/raw.html.ep:5
msgid "Deleted images in 30 days"
msgstr "Deleted images in 30 days"
#: themes/default/templates/index.html.ep:116 themes/default/templates/myfiles.html.ep:127 themes/default/templates/partial/common.js.ep:178 themes/default/templates/partial/common.js.ep:181
msgid "Deletion link"
msgstr "Deletion link"
#: themes/default/templates/gallery.html.ep:10
msgid "Download all images"
msgstr "Download all images"
#: themes/default/templates/index.html.ep:101 themes/default/templates/index.html.ep:99 themes/default/templates/partial/lutim.js.ep:102 themes/default/templates/partial/lutim.js.ep:98
msgid "Download link"
msgstr "Download link"
#: themes/default/templates/index.html.ep:28 themes/default/templates/index.html.ep:31 themes/default/templates/myfiles.html.ep:78 themes/default/templates/myfiles.html.ep:81
msgid "Download zip link"
msgstr "Download zip link"
#: themes/default/templates/index.html.ep:207
msgid "Drag & drop images here"
msgstr "Drag & drop images here"
#: 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 ""
"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."
#: themes/default/templates/index.html.ep:168 themes/default/templates/index.html.ep:199
msgid "Encrypt the image (Lutim does not keep the key)."
msgstr "Encrypt the image (Lutim does not keep the key)."
#: 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 "Error while trying to modify the image."
#: themes/default/templates/stats.html.ep:10
msgid "Evolution of total files"
msgstr "Evolution of total files"
#: themes/default/templates/myfiles.html.ep:126
msgid "Expires at"
msgstr "Expires at"
#: themes/default/templates/myfiles.html.ep:112
msgid "Export localStorage data"
msgstr "Export localStorage data"
#: themes/default/templates/myfiles.html.ep:121
msgid "File name"
msgstr "File name"
#: themes/default/templates/about.html.ep:24
msgid ""
"For more details, see the <a href=\"https://framagit.org/luc/"
"lutim\">homepage of the project</a>."
msgstr ""
"For more details, see the <a href=\"https://framagit.org/luc/"
"lutim\">homepage of the project</a>."
#: themes/default/templates/partial/navbar.html.ep:80
msgid "Fork me!"
msgstr "Fork me!"
#: 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"
msgstr "Gallery link"
#: 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 "Hit Ctrl+C, then Enter to copy the short link"
#: themes/default/templates/layouts/default.html.ep:47
msgid "Homepage"
msgstr "Homepage"
#: themes/default/templates/about.html.ep:20
msgid "How do you pronounce Lutim?"
msgstr "How do you pronounce Lutim?"
#: themes/default/templates/about.html.ep:6
msgid "How does it work?"
msgstr "How does it work?"
#: themes/default/templates/about.html.ep:18
msgid "How to report an image?"
msgstr "How to report an image?"
#: 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 ""
"If the files are deleted if you ask it while posting it, their SHA512 "
"footprint are retained."
#: themes/default/templates/index.html.ep:181 themes/default/templates/index.html.ep:221
msgid "Image URL"
msgstr "Image URL"
#: lib/Lutim/Command/cron/stats.pm:141 themes/default/templates/raw.html.ep:2
msgid "Image delay"
msgstr "Image delay"
#: themes/default/templates/partial/common.js.ep:157
msgid "Image deleted"
msgstr "Image deleted"
#: lib/Lutim/Controller/Image.pm:753
msgid "Image not found."
msgstr "Image not found."
#: themes/default/templates/myfiles.html.ep:113
msgid "Import localStorage data"
msgstr "Import localStorage data"
#: themes/default/templates/partial/navbar.html.ep:69
msgid "Informations"
msgstr "Informations"
#: themes/default/templates/partial/navbar.html.ep:25
msgid "Install webapp"
msgstr "Install webapp"
#: themes/default/templates/partial/navbar.html.ep:21
msgid "Instance's statistics"
msgstr "Instance's statistics"
#: themes/default/templates/about.html.ep:11
msgid "Is it really anonymous?"
msgstr "Is it really anonymous?"
#: themes/default/templates/about.html.ep:9
msgid "Is it really free (as in free beer)?"
msgstr "Is it really free (as in free beer)?"
#: 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 ""
"Juste like you pronounce the French word <a href=\"https://fr.wikipedia.org/"
"wiki/Lutin\">lutin</a> (/ly.tɛ̃/)."
#: themes/default/templates/index.html.ep:171 themes/default/templates/index.html.ep:202
msgid "Keep EXIF tags"
msgstr "Keep EXIF tags"
#: themes/default/templates/partial/navbar.html.ep:43
msgid "Language"
msgstr "Language"
#: themes/default/templates/index.html.ep:136 themes/default/templates/index.html.ep:184 themes/default/templates/index.html.ep:224 themes/default/templates/partial/lutim.js.ep:165
msgid "Let's go!"
msgstr "Let's go!"
#: themes/default/templates/partial/navbar.html.ep:74
msgid "License:"
msgstr "License:"
#: themes/default/templates/index.html.ep:107 themes/default/templates/index.html.ep:109 themes/default/templates/partial/lutim.js.ep:112 themes/default/templates/partial/lutim.js.ep:116
msgid "Link for share on social networks"
msgstr "Link for share on social networks"
#: themes/default/templates/login.html.ep:8
msgid "Login"
msgstr "Login"
#: themes/default/templates/partial/navbar.html.ep:33
msgid "Logout"
msgstr "Logout"
#: 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 can't zip so many images at once, so it splitted your demand in "
"multiple URLs."
#: 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 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."
#: themes/default/templates/about.html.ep:25
msgid "Main developers"
msgstr "Main developers"
#: themes/default/templates/index.html.ep:91 themes/default/templates/index.html.ep:93 themes/default/templates/partial/lutim.js.ep:86 themes/default/templates/partial/lutim.js.ep:89
msgid "Markdown syntax"
msgstr "Markdown syntax"
#: themes/default/templates/partial/myfiles.js.ep:149
msgid "Modify expiration delay"
msgstr "Modify expiration delay"
#: themes/default/templates/myfiles.html.ep:7 themes/default/templates/partial/navbar.html.ep:18
msgid "My images"
msgstr "My images"
#: themes/default/templates/gallery.html.ep:45
msgid "Next (arrow right)"
msgstr "Next (arrow right)"
#: themes/default/templates/partial/myfiles.js.ep:105 themes/default/templates/partial/myfiles.js.ep:132
msgid "No limit"
msgstr "No limit"
#: themes/default/templates/index.html.ep:183 themes/default/templates/index.html.ep:216
msgid "Only images are allowed"
msgstr "Only images are allowed"
#: 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 ""
"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."
#: 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 ""
"Only the uploader! (well, only if he's the only owner of the images' rights "
"before the upload)"
#: themes/default/templates/login.html.ep:12
msgid "Password"
msgstr "Password"
#: themes/default/templates/zip.html.ep:12
msgid "Please click on each URL to download the different zip files."
msgstr "Please click on each URL to download the different zip files."
#. (config('contact')
#: themes/default/templates/about.html.ep:19
msgid "Please contact the administrator: %1"
msgstr "Please contact the administrator: %1"
#: lib/Lutim/Controller/Authent.pm:36
msgid "Please, check your credentials: unable to authenticate."
msgstr "Please, check your credentials: unable to authenticate."
#: themes/default/templates/gallery.html.ep:43
msgid "Previous (arrow left)"
msgstr "Previous (arrow left)"
#: 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"
msgstr "Random image link"
#: themes/default/templates/stats.html.ep:22
msgid "Raw stats"
msgstr "Raw stats"
#: themes/default/templates/myfiles.html.ep:52
msgid "Save changes"
msgstr "Save changes"
#: themes/default/templates/index.html.ep:176
msgid "Send an image"
msgstr "Send an image"
#: 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 "Signin"
#: 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"
msgstr "Something bad happened"
#. ($c->config('contact')
#: lib/Lutim/Controller/Image.pm:760
msgid ""
"Something went wrong when creating the zip file. Try again later or contact "
"the administrator (%1)."
msgstr ""
"Something went wrong when creating the zip file. Try again later or contact "
"the administrator (%1)."
#: themes/default/templates/partial/navbar.html.ep:55
msgid "Support the author"
msgstr "Support the author"
#: themes/default/templates/partial/navbar.html.ep:63
msgid "Support the author on Liberapay"
msgstr "Support the author on Liberapay"
#: themes/default/templates/partial/navbar.html.ep:60
msgid "Support the author on Tipeee"
msgstr "Support the author on Tipeee"
#: 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 ""
"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)."
#: 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 ""
"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."
#: lib/Lutim/Controller/Image.pm:346
msgid "The URL is not valid."
msgstr "The URL is not valid."
#: 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 ""
"The automatic download process will open a tab in your browser for each link."
" You need to allow popups for Lutim."
#: themes/default/templates/partial/myfiles.js.ep:32
msgid "The data has been successfully imported."
msgstr "The data has been successfully imported."
#: lib/Lutim/Controller/Image.pm:159 lib/Lutim/Controller/Image.pm:227
msgid "The delete token is invalid."
msgstr "The delete token is invalid."
#. ($upload->filename)
#: lib/Lutim/Controller/Image.pm:487
msgid "The file %1 is not an image."
msgstr "The file %1 is not an image."
#. ($tx->res->max_message_size)
#. ($c->req->max_message_size)
#. (config('max_file_size')
#: lib/Lutim/Controller/Image.pm:310 lib/Lutim/Controller/Image.pm:379 themes/default/templates/partial/lutim.js.ep:249
msgid "The file exceed the size limit (%1)"
msgstr "The file exceed the size limit (%1)"
#: themes/default/templates/stats.html.ep:12
msgid "The graph's datas are not updated in real-time."
msgstr "The graph's datas are not updated in real-time."
#. ($image->filename)
#: lib/Lutim/Controller/Image.pm:229
msgid "The image %1 has already been deleted."
msgstr "The image %1 has already been deleted."
#. ($image->filename)
#: lib/Lutim/Controller/Image.pm:238 lib/Lutim/Controller/Image.pm:243
msgid "The image %1 has been successfully deleted"
msgstr "The image %1 has been successfully deleted"
#: lib/Lutim/Controller/Image.pm:167
msgid "The image's delay has been successfully modified"
msgstr "The image's delay has been successfully modified"
#: themes/default/templates/index.html.ep:63
msgid "The images are encrypted on the server (Lutim does not keep the key)."
msgstr "The images are encrypted on the server (Lutim does not keep the key)."
#: 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 ""
"The images you post on Lutim can be stored indefinitely or be deleted at "
"first view or after a delay selected from those proposed."
#: themes/default/templates/partial/gallery.js.ep:257
msgid "There is XXXX image(s) in the gallery"
msgstr "There is XXXX image(s) in the gallery"
#. ($c->config->{contact})
#: lib/Lutim/Controller/Image.pm:484
msgid "There is no more available URL. Retry or contact the administrator. %1"
msgstr ""
"There is no more available URL. Retry or contact the administrator. %1"
#: themes/default/templates/gallery.html.ep:30
msgid "Toggle fullscreen"
msgstr "Toggle fullscreen"
#: themes/default/templates/partial/navbar.html.ep:8
msgid "Toggle navigation"
msgstr "Toggle navigation"
#: lib/Lutim/Command/cron/stats.pm:150 themes/default/templates/raw.html.ep:11
msgid "Total"
msgstr "Total"
#: themes/default/templates/index.html.ep:78 themes/default/templates/partial/lutim.js.ep:17
msgid "Tweet it!"
msgstr "Tweet it!"
#: themes/default/templates/partial/common.js.ep:110 themes/default/templates/partial/common.js.ep:90
msgid "Unable to copy to clipboard"
msgstr "Unable to copy to clipboard"
#. ($short)
#: lib/Lutim/Controller/Image.pm:107 lib/Lutim/Controller/Image.pm:201 lib/Lutim/Controller/Image.pm:272
msgid "Unable to find the image %1."
msgstr "Unable to find the image %1."
#: lib/Lutim/Controller/Image.pm:573 lib/Lutim/Controller/Image.pm:618 lib/Lutim/Controller/Image.pm:657 lib/Lutim/Controller/Image.pm:700 lib/Lutim/Controller/Image.pm:712 lib/Lutim/Controller/Image.pm:723 lib/Lutim/Controller/Image.pm:750 lib/Lutim/Plugin/Helpers.pm:88
msgid "Unable to find the image: it has been deleted."
msgstr "Unable to find the image: it has been deleted."
#: lib/Lutim/Controller/Image.pm:144
msgid "Unable to get counter"
msgstr "Unable to get counter"
#: themes/default/templates/about.html.ep:17
msgid ""
"Unlike many image sharing services, you don't give us rights on uploaded "
"images."
msgstr ""
"Unlike many image sharing services, you don't give us rights on uploaded "
"images."
#: themes/default/templates/index.html.ep:180 themes/default/templates/index.html.ep:219
msgid "Upload an image with its URL"
msgstr "Upload an image with its URL"
#: themes/default/templates/myfiles.html.ep:125
msgid "Uploaded at"
msgstr "Uploaded at"
#: themes/default/templates/stats.html.ep:6
msgid "Uploaded files by days"
msgstr "Uploaded files by days"
#. ($c->app->config('contact')
#: lib/Lutim/Plugin/Helpers.pm:221
msgid ""
"Uploading is currently disabled, please try later or contact the "
"administrator (%1)."
msgstr ""
"Uploading is currently disabled, please try later or contact the "
"administrator (%1)."
#: themes/default/templates/index.html.ep:83 themes/default/templates/index.html.ep:85 themes/default/templates/myfiles.html.ep:122 themes/default/templates/partial/lutim.js.ep:72 themes/default/templates/partial/lutim.js.ep:76
msgid "View link"
msgstr "View link"
#: themes/default/templates/about.html.ep:22
msgid "What about the software which provides the service?"
msgstr "What about the software which provides the service?"
#: themes/default/templates/about.html.ep:3
msgid "What is Lutim?"
msgstr "What is Lutim?"
#: themes/default/templates/about.html.ep:15
msgid "Who owns rights on images uploaded on Lutim?"
msgstr "Who owns rights on images uploaded on Lutim?"
#: 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 ""
"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!"
#: 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 ""
"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>."
#: themes/default/templates/zip.html.ep:6
msgid "You asked to download a zip archive for too much files."
msgstr "You asked to download a zip archive for too much files."
#: 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 ""
"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."
#: lib/Lutim/Controller/Authent.pm:27
msgid "You have been successfully logged in."
msgstr "You have been successfully logged in."
#: lib/Lutim/Controller/Authent.pm:66 themes/default/templates/logout.html.ep:3
msgid "You have been successfully logged out."
msgstr "You have been successfully logged out."
#: themes/default/templates/gallery.html.ep:31
msgid "Zoom in/out"
msgstr "Zoom in/out"
#: themes/default/templates/about.html.ep:27
msgid "and on"
msgstr "and on"
#: themes/default/templates/about.html.ep:40
msgid "arabic translation"
msgstr "arabic translation"
#: themes/default/templates/about.html.ep:27
msgid "core developer"
msgstr "core developer"
#: lib/Lutim.pm:348 lib/Lutim/Command/cron/stats.pm:145 lib/Lutim/Command/cron/stats.pm:159 lib/Lutim/Command/cron/stats.pm:176 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 "no time limit"
#: themes/default/templates/about.html.ep:38
msgid "occitan translation"
msgstr "occitan translation"
#: themes/default/templates/about.html.ep:27
msgid "on"
msgstr "on"
#: themes/default/templates/about.html.ep:39
msgid "paste image to upload ability"
msgstr "paste image to upload ability"
#: themes/default/templates/about.html.ep:41
msgid "russian translation"
msgstr "russian translation"
#: themes/default/templates/about.html.ep:36
msgid "spanish translation"
msgstr "spanish translation"
#: themes/default/templates/about.html.ep:28
msgid "webapp developer"
msgstr "webapp developer"

View File

@@ -0,0 +1,684 @@
# Lutim language file
# Copyright (C) 2014 Luc Didry
# This file is distributed under the same license as the Lutim package.
#
# Translators:
# Translators:
# Luc Didry <luc@didry.org>, 2015
# Luc Didry <luc@framasoft.org>, 2018. #zanata
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"PO-Revision-Date: 2018-07-29 08:17+0000\n"
"Last-Translator: Copied by Zanata <copied-by-zanata@zanata.org>\n"
"Language-Team: Spanish (http://www.transifex.com/fiat-tux/lutim/language/es/"
")\n"
"Language: es\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Zanata 4.5.0\n"
#. (7)
#. (30)
#. ($delay)
#. (config('max_delay')
#: lib/Lutim/Command/cron/stats.pm:147 lib/Lutim/Command/cron/stats.pm:148 lib/Lutim/Command/cron/stats.pm:161 lib/Lutim/Command/cron/stats.pm:162 lib/Lutim/Command/cron/stats.pm:178 lib/Lutim/Command/cron/stats.pm:179 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 días"
#. ($total)
#: themes/default/templates/stats.html.ep:2
msgid "%1 sent images on this instance from beginning."
msgstr "%1 imágenes enviadas a esta instancia desde el inicio."
#: themes/default/templates/index.html.ep:208
msgid "-or-"
msgstr "-o-"
#: lib/Lutim.pm:350 lib/Lutim/Command/cron/stats.pm:149 lib/Lutim/Command/cron/stats.pm:163 lib/Lutim/Command/cron/stats.pm:180 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 año"
#: lib/Lutim.pm:349 lib/Lutim/Command/cron/stats.pm:146 lib/Lutim/Command/cron/stats.pm:160 lib/Lutim/Command/cron/stats.pm:177 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 horas"
#: themes/default/templates/partial/myfiles.js.ep:180
msgid ": Error while trying to get the counter."
msgstr ": Error al intentar obtener el contador."
#: themes/default/templates/partial/navbar.html.ep:77
msgid "About"
msgstr ""
#: lib/Lutim/Command/cron/stats.pm:142 themes/default/templates/raw.html.ep:3
msgid "Active images"
msgstr ""
#: lib/Lutim/Controller/Image.pm:327
msgid "An error occured while downloading the image."
msgstr "Error al intentar modificar la imagen."
#: themes/default/templates/zip.html.ep:2
msgid "Archives download"
msgstr ""
#: 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"
msgstr "Volver a la página inicial"
#: themes/default/templates/index.html.ep:211 themes/default/templates/index.html.ep:212
msgid "Click to open the file browser"
msgstr "Clic para abrir el explorador de archivos"
#: themes/default/templates/myfiles.html.ep:51
msgid "Close"
msgstr "Cerrar"
#: themes/default/templates/gallery.html.ep:29
msgid "Close (Esc)"
msgstr "Cerrar (Esc)"
#: themes/default/templates/about.html.ep:30
msgid "Contributors"
msgstr "Contribuidores"
#: themes/default/templates/partial/common.js.ep:113 themes/default/templates/partial/common.js.ep:93
msgid "Copied to clipboard"
msgstr ""
#: 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 "Copiar todos los enlaces de visualización al portapapeles"
#: themes/default/templates/index.html.ep:103 themes/default/templates/index.html.ep:111 themes/default/templates/index.html.ep:18 themes/default/templates/index.html.ep:36 themes/default/templates/index.html.ep:54 themes/default/templates/index.html.ep:87 themes/default/templates/index.html.ep:95 themes/default/templates/myfiles.html.ep:104 themes/default/templates/myfiles.html.ep:68 themes/default/templates/myfiles.html.ep:86 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:142
msgid "Copy to clipboard"
msgstr "Copiar al portapapeles"
#: themes/default/templates/myfiles.html.ep:123
msgid "Counter"
msgstr "Contador"
#: themes/default/templates/stats.html.ep:18
msgid "Delay repartition chart for disabled images"
msgstr ""
#: themes/default/templates/stats.html.ep:15
msgid "Delay repartition chart for enabled images"
msgstr ""
#: 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?"
msgstr "¿Borrar en la primera vista?"
#: lib/Lutim/Command/cron/stats.pm:143 themes/default/templates/raw.html.ep:4
msgid "Deleted images"
msgstr ""
#: lib/Lutim/Command/cron/stats.pm:144 themes/default/templates/raw.html.ep:5
msgid "Deleted images in 30 days"
msgstr ""
#: themes/default/templates/index.html.ep:116 themes/default/templates/myfiles.html.ep:127 themes/default/templates/partial/common.js.ep:178 themes/default/templates/partial/common.js.ep:181
msgid "Deletion link"
msgstr "Enlace para borrar"
#: themes/default/templates/gallery.html.ep:10
msgid "Download all images"
msgstr "Descargar todas las imágenes"
#: themes/default/templates/index.html.ep:101 themes/default/templates/index.html.ep:99 themes/default/templates/partial/lutim.js.ep:102 themes/default/templates/partial/lutim.js.ep:98
msgid "Download link"
msgstr "Enlace de descarga"
#: themes/default/templates/index.html.ep:28 themes/default/templates/index.html.ep:31 themes/default/templates/myfiles.html.ep:78 themes/default/templates/myfiles.html.ep:81
msgid "Download zip link"
msgstr "Enlace de descarga del archivo de las imágenes"
#: themes/default/templates/index.html.ep:207
msgid "Drag & drop images here"
msgstr "Arrastre y suelte imágenes aquí"
#: 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 ""
"Arrastre y suelte una imagen en el área apropiada, o use el método "
"tradicional para enviar ficheros, y Lutim proporcionará cuatro URLs. Una "
"para ver la imagen, otra para descargarla directamente, una que upede usar "
"en redes sociales, y una última para borrar la imagen cuando lo desee."
#: themes/default/templates/index.html.ep:168 themes/default/templates/index.html.ep:199
msgid "Encrypt the image (Lutim does not keep the key)."
msgstr "Las imágenes se cifran en el servidor (Lutim no guarda la clave)."
#: 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 "Error al intentar modificar la imagen."
#: themes/default/templates/stats.html.ep:10
msgid "Evolution of total files"
msgstr "Evolución de archivos en total"
#: themes/default/templates/myfiles.html.ep:126
msgid "Expires at"
msgstr "Expira"
#: themes/default/templates/myfiles.html.ep:112
msgid "Export localStorage data"
msgstr ""
#: themes/default/templates/myfiles.html.ep:121
msgid "File name"
msgstr "Nombre de archivo"
#: themes/default/templates/about.html.ep:24
msgid ""
"For more details, see the <a href=\"https://framagit.org/luc/"
"lutim\">homepage of the project</a>."
msgstr ""
"Para más detalles, vea la <a href=\"https://framagit.org/luc/lutim\">página "
"del proyecto</a>."
#: themes/default/templates/partial/navbar.html.ep:80
msgid "Fork me!"
msgstr "¡Clóname!"
#: 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"
msgstr "Enlace a la galería"
#: 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 "Presione Ctrl + C, entonces Ingresar para copiar el enlace"
#: themes/default/templates/layouts/default.html.ep:47
msgid "Homepage"
msgstr "Página inicial"
#: themes/default/templates/about.html.ep:20
msgid "How do you pronounce Lutim?"
msgstr "¿Cómo se pronuncia Lutim?"
#: themes/default/templates/about.html.ep:6
msgid "How does it work?"
msgstr "¿Cómo funciona?"
#: themes/default/templates/about.html.ep:18
msgid "How to report an image?"
msgstr "¿Cómo informar sobre una imagen?"
#: 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 ""
"Si los ficheros se borran por haberlo solicitado al enviarlos, se retiene su "
"huella digital SHA512."
#: themes/default/templates/index.html.ep:181 themes/default/templates/index.html.ep:221
msgid "Image URL"
msgstr "URL de la imagen"
#: lib/Lutim/Command/cron/stats.pm:141 themes/default/templates/raw.html.ep:2
msgid "Image delay"
msgstr ""
#: themes/default/templates/partial/common.js.ep:157
msgid "Image deleted"
msgstr ""
#: lib/Lutim/Controller/Image.pm:753
msgid "Image not found."
msgstr "Imagen no encontrada."
#: themes/default/templates/myfiles.html.ep:113
msgid "Import localStorage data"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:69
msgid "Informations"
msgstr "Informaciones"
#: themes/default/templates/partial/navbar.html.ep:25
msgid "Install webapp"
msgstr "Instalar webapp"
#: themes/default/templates/partial/navbar.html.ep:21
msgid "Instance's statistics"
msgstr ""
#: themes/default/templates/about.html.ep:11
msgid "Is it really anonymous?"
msgstr "¿Es realmente anónimo?"
#: themes/default/templates/about.html.ep:9
msgid "Is it really free (as in free beer)?"
msgstr "¿Es realmente gratis?"
#: 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 ""
"Tal y como se pronuncia la palabra francesa <a href=\"https://fr.wikipedia."
"org/wiki/Lutin\">lutin</a> (/ly.tɛ̃/)."
#: themes/default/templates/index.html.ep:171 themes/default/templates/index.html.ep:202
msgid "Keep EXIF tags"
msgstr "Mantener las etiquetas EXIF"
#: themes/default/templates/partial/navbar.html.ep:43
msgid "Language"
msgstr "Lengua"
#: themes/default/templates/index.html.ep:136 themes/default/templates/index.html.ep:184 themes/default/templates/index.html.ep:224 themes/default/templates/partial/lutim.js.ep:165
msgid "Let's go!"
msgstr "¡Vamos allá!"
#: themes/default/templates/partial/navbar.html.ep:74
msgid "License:"
msgstr "Licencia:"
#: themes/default/templates/index.html.ep:107 themes/default/templates/index.html.ep:109 themes/default/templates/partial/lutim.js.ep:112 themes/default/templates/partial/lutim.js.ep:116
msgid "Link for share on social networks"
msgstr "Enlace para compartir en redes sociales"
#: themes/default/templates/login.html.ep:8
msgid "Login"
msgstr "Login"
#: themes/default/templates/partial/navbar.html.ep:33
msgid "Logout"
msgstr "Salir"
#: 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 ""
#: 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 es un servicio de alojamiento de imágenes anónimo y gratuito. También "
"es el nombre del software libre que proporciona este servicio."
#: themes/default/templates/about.html.ep:25
msgid "Main developers"
msgstr "Desarrolladores principales"
#: themes/default/templates/index.html.ep:91 themes/default/templates/index.html.ep:93 themes/default/templates/partial/lutim.js.ep:86 themes/default/templates/partial/lutim.js.ep:89
msgid "Markdown syntax"
msgstr "Sintaxis de Markdown"
#: themes/default/templates/partial/myfiles.js.ep:149
msgid "Modify expiration delay"
msgstr ""
#: themes/default/templates/myfiles.html.ep:7 themes/default/templates/partial/navbar.html.ep:18
msgid "My images"
msgstr "Mis Imágenes"
#: themes/default/templates/gallery.html.ep:45
msgid "Next (arrow right)"
msgstr ""
#: themes/default/templates/partial/myfiles.js.ep:105 themes/default/templates/partial/myfiles.js.ep:132
msgid "No limit"
msgstr "Sin fecha de caducidad"
#: themes/default/templates/index.html.ep:183 themes/default/templates/index.html.ep:216
msgid "Only images are allowed"
msgstr "Sólo se admiten imágenes"
#: 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 ""
"Sólo se enumeran aquí las imágenes enviadas con este navegador. Los detalles "
"se almacenan en localStorage: si elimina sus datos localStorage, perderás "
"estos detalles."
#: 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 ""
"¡Sólo el usuario! (bueno, sólo si él/ela es el único titular de los derechos "
"de las imágenes antes de subirlas)"
#: themes/default/templates/login.html.ep:12
msgid "Password"
msgstr "Contraseña"
#: themes/default/templates/zip.html.ep:12
msgid "Please click on each URL to download the different zip files."
msgstr ""
#. (config('contact')
#: themes/default/templates/about.html.ep:19
msgid "Please contact the administrator: %1"
msgstr "Por favor, contacte con el administrador: %1"
#: lib/Lutim/Controller/Authent.pm:36
msgid "Please, check your credentials: unable to authenticate."
msgstr ""
#: themes/default/templates/gallery.html.ep:43
msgid "Previous (arrow left)"
msgstr ""
#: 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"
msgstr ""
#: themes/default/templates/stats.html.ep:22
msgid "Raw stats"
msgstr ""
#: themes/default/templates/myfiles.html.ep:52
msgid "Save changes"
msgstr "Guardar los cambios"
#: themes/default/templates/index.html.ep:176
msgid "Send an image"
msgstr "Enviar una imagen"
#: 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 ""
#: 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"
msgstr "Algo malo ha pasado"
#. ($c->config('contact')
#: lib/Lutim/Controller/Image.pm:760
msgid ""
"Something went wrong when creating the zip file. Try again later or contact "
"the administrator (%1)."
msgstr ""
"Algo malo ha pasado. Inténtelo de nuevo más tarde o contacte con el "
"administrador (%1)."
#: themes/default/templates/partial/navbar.html.ep:55
msgid "Support the author"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:63
msgid "Support the author on Liberapay"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:60
msgid "Support the author on Tipeee"
msgstr ""
#: 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 ""
"La dirección IP del remitente de la imagen se retiene durante un tiempo, que "
"depende de lo que elija el administrador (para la instancia oficial, que "
"está localizada en Francia, es un año)."
#: 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 ""
"El software Lutim es <a href=\"http://es.wikipedia.org/wiki/"
"Software_libre\">software libre</a>, lo que le permite descargarlo e "
"instalarlo en su propio servidor. Eche un vistazo a la licencia <a href="
"\"https://www.gnu.org/licenses/agpl-3.0.html\">AGPL</a> para ver qué puede "
"hacer."
#: lib/Lutim/Controller/Image.pm:346
msgid "The URL is not valid."
msgstr "La URL no es válida."
#: 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 ""
#: themes/default/templates/partial/myfiles.js.ep:32
msgid "The data has been successfully imported."
msgstr ""
#: lib/Lutim/Controller/Image.pm:159 lib/Lutim/Controller/Image.pm:227
msgid "The delete token is invalid."
msgstr "El código de borrado no es válido."
#. ($upload->filename)
#: lib/Lutim/Controller/Image.pm:487
msgid "The file %1 is not an image."
msgstr "El archivo %1 no es una imagen."
#. ($tx->res->max_message_size)
#. ($c->req->max_message_size)
#. (config('max_file_size')
#: lib/Lutim/Controller/Image.pm:310 lib/Lutim/Controller/Image.pm:379 themes/default/templates/partial/lutim.js.ep:249
msgid "The file exceed the size limit (%1)"
msgstr "El archivo supera el límite de tamaño (%1)"
#: themes/default/templates/stats.html.ep:12
msgid "The graph's datas are not updated in real-time."
msgstr "Los datos del gráfico no se actualizan en tiempo real."
#. ($image->filename)
#: lib/Lutim/Controller/Image.pm:229
msgid "The image %1 has already been deleted."
msgstr "La imagen %1 ya se ha borrado."
#. ($image->filename)
#: lib/Lutim/Controller/Image.pm:238 lib/Lutim/Controller/Image.pm:243
msgid "The image %1 has been successfully deleted"
msgstr "La imagen %1 se ha borrado correctamente"
#: lib/Lutim/Controller/Image.pm:167
msgid "The image's delay has been successfully modified"
msgstr "Se ha modificado correctamente el tiempo de la imagen"
#: themes/default/templates/index.html.ep:63
msgid "The images are encrypted on the server (Lutim does not keep the key)."
msgstr "Las imágenes se cifran en el servidor (Lutim no guarda la clave)."
#: 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 ""
"Puede, opcionalmente, solicitar que la imagen publicada en Lutim se elimine "
"con la primera vista (o descarga) o tras un tiempo seleccionado de entre "
"varios propuestos."
#: themes/default/templates/partial/gallery.js.ep:257
msgid "There is XXXX image(s) in the gallery"
msgstr ""
#. ($c->config->{contact})
#: lib/Lutim/Controller/Image.pm:484
msgid "There is no more available URL. Retry or contact the administrator. %1"
msgstr ""
"No más URL disponibles. Inténtelo de nuevo o contacte con el administrador. "
"%1"
#: themes/default/templates/gallery.html.ep:30
msgid "Toggle fullscreen"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:8
msgid "Toggle navigation"
msgstr ""
#: lib/Lutim/Command/cron/stats.pm:150 themes/default/templates/raw.html.ep:11
msgid "Total"
msgstr ""
#: themes/default/templates/index.html.ep:78 themes/default/templates/partial/lutim.js.ep:17
msgid "Tweet it!"
msgstr "¡Tuitéalo!"
#: themes/default/templates/partial/common.js.ep:110 themes/default/templates/partial/common.js.ep:90
msgid "Unable to copy to clipboard"
msgstr ""
#. ($short)
#: lib/Lutim/Controller/Image.pm:107 lib/Lutim/Controller/Image.pm:201 lib/Lutim/Controller/Image.pm:272
msgid "Unable to find the image %1."
msgstr "No se ha podido encontrar la imagen %1."
#: lib/Lutim/Controller/Image.pm:573 lib/Lutim/Controller/Image.pm:618 lib/Lutim/Controller/Image.pm:657 lib/Lutim/Controller/Image.pm:700 lib/Lutim/Controller/Image.pm:712 lib/Lutim/Controller/Image.pm:723 lib/Lutim/Controller/Image.pm:750 lib/Lutim/Plugin/Helpers.pm:88
msgid "Unable to find the image: it has been deleted."
msgstr "No se ha podido encontrar la imagen: ha sido borrada."
#: lib/Lutim/Controller/Image.pm:144
msgid "Unable to get counter"
msgstr "Imposible recuperar el contador"
#: themes/default/templates/about.html.ep:17
msgid ""
"Unlike many image sharing services, you don't give us rights on uploaded "
"images."
msgstr ""
"A diferencia de muchos servicios de compartición de imágenes, usted no cede "
"los derechos de las imágenes que sube."
#: themes/default/templates/index.html.ep:180 themes/default/templates/index.html.ep:219
msgid "Upload an image with its URL"
msgstr "Subir una imagen con la URL"
#: themes/default/templates/myfiles.html.ep:125
msgid "Uploaded at"
msgstr "Enviado el"
#: themes/default/templates/stats.html.ep:6
msgid "Uploaded files by days"
msgstr "Archivos enviados por día"
#. ($c->app->config('contact')
#: lib/Lutim/Plugin/Helpers.pm:221
msgid ""
"Uploading is currently disabled, please try later or contact the "
"administrator (%1)."
msgstr ""
"La carga está deshabilitada en estos momentos, por favor inténtelo más tarde "
"o contacte con el administrador (%1)."
#: themes/default/templates/index.html.ep:83 themes/default/templates/index.html.ep:85 themes/default/templates/myfiles.html.ep:122 themes/default/templates/partial/lutim.js.ep:72 themes/default/templates/partial/lutim.js.ep:76
msgid "View link"
msgstr "Enlace de visualización"
#: themes/default/templates/about.html.ep:22
msgid "What about the software which provides the service?"
msgstr "¿Y qué hay sobre el software que proporciona el servicio?"
#: themes/default/templates/about.html.ep:3
msgid "What is Lutim?"
msgstr "¿Qué es Lutim?"
#: themes/default/templates/about.html.ep:15
msgid "Who owns rights on images uploaded on Lutim?"
msgstr "¿Quién posee los derechos de las imágenes que se suben a Lutim?"
#: 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 ""
"¡Sí, lo es! Por otro lado, por razones legales, se almacena la dirección IP "
"cuando se envía una imagen. Que no cunda el pánico, ¡es el caso habitual "
"para todos los sitios a los cuales se envían ficheros!"
#: 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 ""
"¡Sí, lo es! Por otro lado, si quiere ayudar a apoyar al desarrollador, puede "
"hacerlo vía <a href=\"https://www.tipeee.com/fiat-tux\">Tipeee</a> o con <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 ""
#: 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 ""
"Puede, opcionalmente, solicitar que la imagen publicada en Lutim se elimine "
"con la primera vista (o descarga) o tras un tiempo seleccionado de entre "
"varios propuestos."
#: lib/Lutim/Controller/Authent.pm:27
msgid "You have been successfully logged in."
msgstr ""
#: lib/Lutim/Controller/Authent.pm:66 themes/default/templates/logout.html.ep:3
msgid "You have been successfully logged out."
msgstr ""
#: themes/default/templates/gallery.html.ep:31
msgid "Zoom in/out"
msgstr ""
#: themes/default/templates/about.html.ep:27
msgid "and on"
msgstr "y en"
#: themes/default/templates/about.html.ep:40
msgid "arabic translation"
msgstr ""
#: themes/default/templates/about.html.ep:27
msgid "core developer"
msgstr "desarrollador principal"
#: lib/Lutim.pm:348 lib/Lutim/Command/cron/stats.pm:145 lib/Lutim/Command/cron/stats.pm:159 lib/Lutim/Command/cron/stats.pm:176 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 "Sin tiempo límite"
#: themes/default/templates/about.html.ep:38
msgid "occitan translation"
msgstr "traducción al occitano"
#: themes/default/templates/about.html.ep:27
msgid "on"
msgstr "en"
#: themes/default/templates/about.html.ep:39
msgid "paste image to upload ability"
msgstr ""
#: themes/default/templates/about.html.ep:41
msgid "russian translation"
msgstr ""
#: themes/default/templates/about.html.ep:36
msgid "spanish translation"
msgstr "traducción al español"
#: themes/default/templates/about.html.ep:28
msgid "webapp developer"
msgstr "desarrollador de la webapp"

View File

@@ -0,0 +1,696 @@
# Lutim language file
# Copyright (C) 2014 Luc Didry
# This file is distributed under the same license as the Lutim package.
#
# Translators:
# Translators:
# Luc Didry <luc@didry.org>, 2015
# Luc Didry <luc@framasoft.org>, 2018. #zanata
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"PO-Revision-Date: 2018-07-29 08:17+0000\n"
"Last-Translator: Copied by Zanata <copied-by-zanata@zanata.org>\n"
"Language-Team: French (http://www.transifex.com/fiat-tux/lutim/language/fr/)\n"
"Language: fr\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Zanata 4.5.0\n"
#. (7)
#. (30)
#. ($delay)
#. (config('max_delay')
#: lib/Lutim/Command/cron/stats.pm:147 lib/Lutim/Command/cron/stats.pm:148 lib/Lutim/Command/cron/stats.pm:161 lib/Lutim/Command/cron/stats.pm:162 lib/Lutim/Command/cron/stats.pm:178 lib/Lutim/Command/cron/stats.pm:179 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 jours"
#. ($total)
#: themes/default/templates/stats.html.ep:2
msgid "%1 sent images on this instance from beginning."
msgstr "%1 images envoyées sur cette instance depuis le début."
#: themes/default/templates/index.html.ep:208
msgid "-or-"
msgstr "-ou-"
#: lib/Lutim.pm:350 lib/Lutim/Command/cron/stats.pm:149 lib/Lutim/Command/cron/stats.pm:163 lib/Lutim/Command/cron/stats.pm:180 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 an"
#: lib/Lutim.pm:349 lib/Lutim/Command/cron/stats.pm:146 lib/Lutim/Command/cron/stats.pm:160 lib/Lutim/Command/cron/stats.pm:177 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 heures"
#: themes/default/templates/partial/myfiles.js.ep:180
msgid ": Error while trying to get the counter."
msgstr " : Erreur en essayant de récupérer le compteur."
#: themes/default/templates/partial/navbar.html.ep:77
msgid "About"
msgstr "À propos"
#: lib/Lutim/Command/cron/stats.pm:142 themes/default/templates/raw.html.ep:3
msgid "Active images"
msgstr "Images actives"
#: lib/Lutim/Controller/Image.pm:327
msgid "An error occured while downloading the image."
msgstr "Une erreur est survenue lors du téléchargement de limage."
#: themes/default/templates/zip.html.ep:2
msgid "Archives download"
msgstr "Téléchargement darchives"
#: 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"
msgstr "Retour à la page daccueil"
#: themes/default/templates/index.html.ep:211 themes/default/templates/index.html.ep:212
msgid "Click to open the file browser"
msgstr "Cliquez pour utiliser le navigateur de fichier"
#: themes/default/templates/myfiles.html.ep:51
msgid "Close"
msgstr "Fermer"
#: themes/default/templates/gallery.html.ep:29
msgid "Close (Esc)"
msgstr "Fermer (Esc)"
#: themes/default/templates/about.html.ep:30
msgid "Contributors"
msgstr "Contributeurs"
#: themes/default/templates/partial/common.js.ep:113 themes/default/templates/partial/common.js.ep:93
msgid "Copied to clipboard"
msgstr "Copié dans le presse-papier"
#: 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 "Copier tous les liens de visualisation dans le presse-papier"
#: themes/default/templates/index.html.ep:103 themes/default/templates/index.html.ep:111 themes/default/templates/index.html.ep:18 themes/default/templates/index.html.ep:36 themes/default/templates/index.html.ep:54 themes/default/templates/index.html.ep:87 themes/default/templates/index.html.ep:95 themes/default/templates/myfiles.html.ep:104 themes/default/templates/myfiles.html.ep:68 themes/default/templates/myfiles.html.ep:86 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:142
msgid "Copy to clipboard"
msgstr "Copier dans le presse-papier"
#: themes/default/templates/myfiles.html.ep:123
msgid "Counter"
msgstr "Compteur"
#: themes/default/templates/stats.html.ep:18
msgid "Delay repartition chart for disabled images"
msgstr "Graphe de répartition des délais pour les images supprimées"
#: themes/default/templates/stats.html.ep:15
msgid "Delay repartition chart for enabled images"
msgstr "Graphe de répartition des délais pour les images actives"
#: 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?"
msgstr "Supprimer au premier accès ?"
#: lib/Lutim/Command/cron/stats.pm:143 themes/default/templates/raw.html.ep:4
msgid "Deleted images"
msgstr "Images supprimées"
#: lib/Lutim/Command/cron/stats.pm:144 themes/default/templates/raw.html.ep:5
msgid "Deleted images in 30 days"
msgstr "Images supprimées dans 30 jours"
#: themes/default/templates/index.html.ep:116 themes/default/templates/myfiles.html.ep:127 themes/default/templates/partial/common.js.ep:178 themes/default/templates/partial/common.js.ep:181
msgid "Deletion link"
msgstr "Lien de suppression"
#: themes/default/templates/gallery.html.ep:10
msgid "Download all images"
msgstr "Télécharger toutes les images"
#: themes/default/templates/index.html.ep:101 themes/default/templates/index.html.ep:99 themes/default/templates/partial/lutim.js.ep:102 themes/default/templates/partial/lutim.js.ep:98
msgid "Download link"
msgstr "Lien de téléchargement"
#: themes/default/templates/index.html.ep:28 themes/default/templates/index.html.ep:31 themes/default/templates/myfiles.html.ep:78 themes/default/templates/myfiles.html.ep:81
msgid "Download zip link"
msgstr "Lien de téléchargement de larchive des images"
#: themes/default/templates/index.html.ep:207
msgid "Drag & drop images here"
msgstr "Déposez vos images ici"
#: 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 ""
"Faites glisser des images dans la zone prévue à cet effet ou sélectionnez un "
"fichier de façon classique et Lutim vous fournira quatre URLs en retour. Une "
"pour afficher limage, une autre pour la télécharger directement, une pour "
"lutiliser sur les réseaux sociaux et une dernière pour supprimer votre "
"image quand vous le souhaitez"
#: themes/default/templates/index.html.ep:168 themes/default/templates/index.html.ep:199
msgid "Encrypt the image (Lutim does not keep the key)."
msgstr "Chiffrer limage (Lutim ne stocke pas la clé)."
#: 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 "Une erreur est survenue en essayant de modifier limage."
#: themes/default/templates/stats.html.ep:10
msgid "Evolution of total files"
msgstr "Évolution du nombre total de fichiers"
#: themes/default/templates/myfiles.html.ep:126
msgid "Expires at"
msgstr "Expire le"
#: themes/default/templates/myfiles.html.ep:112
msgid "Export localStorage data"
msgstr "Exporter les données localStorage"
#: themes/default/templates/myfiles.html.ep:121
msgid "File name"
msgstr "Nom du fichier"
#: themes/default/templates/about.html.ep:24
msgid ""
"For more details, see the <a href=\"https://framagit.org/luc/"
"lutim\">homepage of the project</a>."
msgstr ""
"Pour plus de détails, consultez la page <a href=\"https://framagit.org/luc/"
"lutim\">Github</a> du projet."
#: themes/default/templates/partial/navbar.html.ep:80
msgid "Fork me!"
msgstr "Créez un fork !"
#: 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"
msgstr "Lien vers la galerie"
#: 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 "Faites Ctrl+C puis appuyez sur la touche Entrée pour copier le lien"
#: themes/default/templates/layouts/default.html.ep:47
msgid "Homepage"
msgstr "Accueil"
#: themes/default/templates/about.html.ep:20
msgid "How do you pronounce Lutim?"
msgstr "Comment doit-on prononcer Lutim ?"
#: themes/default/templates/about.html.ep:6
msgid "How does it work?"
msgstr "Comment ça marche ?"
#: themes/default/templates/about.html.ep:18
msgid "How to report an image?"
msgstr "Comment peut-on faire pour signaler une image ?"
#: 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 ""
"Si les fichiers sont bien supprimés si vous en avez exprimé le choix, leur "
"empreinte SHA512 est toutefois conservée."
#: themes/default/templates/index.html.ep:181 themes/default/templates/index.html.ep:221
msgid "Image URL"
msgstr "URL de limage"
#: lib/Lutim/Command/cron/stats.pm:141 themes/default/templates/raw.html.ep:2
msgid "Image delay"
msgstr "Durée de rétention de limage"
#: themes/default/templates/partial/common.js.ep:157
msgid "Image deleted"
msgstr "Image supprimée"
#: lib/Lutim/Controller/Image.pm:753
msgid "Image not found."
msgstr "Image non trouvée."
#: themes/default/templates/myfiles.html.ep:113
msgid "Import localStorage data"
msgstr "Importer des données localStorage"
#: themes/default/templates/partial/navbar.html.ep:69
msgid "Informations"
msgstr "Informations"
#: themes/default/templates/partial/navbar.html.ep:25
msgid "Install webapp"
msgstr "Installer la webapp"
#: themes/default/templates/partial/navbar.html.ep:21
msgid "Instance's statistics"
msgstr "Statistiques de linstance"
#: themes/default/templates/about.html.ep:11
msgid "Is it really anonymous?"
msgstr "Cest vraiment anonyme ?"
#: themes/default/templates/about.html.ep:9
msgid "Is it really free (as in free beer)?"
msgstr "Cest vraiment gratuit ?"
#: 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 ""
"Comme on prononce <a href=\"https://fr.wikipedia.org/wiki/Lutin\">lutin</a> "
"(/ly.tɛ̃/)."
#: themes/default/templates/index.html.ep:171 themes/default/templates/index.html.ep:202
msgid "Keep EXIF tags"
msgstr "Conserver les données EXIF"
#: themes/default/templates/partial/navbar.html.ep:43
msgid "Language"
msgstr "Langue"
#: themes/default/templates/index.html.ep:136 themes/default/templates/index.html.ep:184 themes/default/templates/index.html.ep:224 themes/default/templates/partial/lutim.js.ep:165
msgid "Let's go!"
msgstr "Allons-y !"
#: themes/default/templates/partial/navbar.html.ep:74
msgid "License:"
msgstr "Licence :"
#: themes/default/templates/index.html.ep:107 themes/default/templates/index.html.ep:109 themes/default/templates/partial/lutim.js.ep:112 themes/default/templates/partial/lutim.js.ep:116
msgid "Link for share on social networks"
msgstr "Lien pour partager sur les réseaux sociaux"
#: themes/default/templates/login.html.ep:8
msgid "Login"
msgstr "Connexion"
#: themes/default/templates/partial/navbar.html.ep:33
msgid "Logout"
msgstr "Déconnexion"
#: 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 peut zipper autant dimages à la fois, votre demande a donc été "
"découpée en plusieurs URL."
#: 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 est un service gratuit et anonyme dhébergement dimages. Il sagit "
"aussi du nom du logiciel (libre) qui fournit ce service."
#: themes/default/templates/about.html.ep:25
msgid "Main developers"
msgstr "Développeurs de lapplication"
#: themes/default/templates/index.html.ep:91 themes/default/templates/index.html.ep:93 themes/default/templates/partial/lutim.js.ep:86 themes/default/templates/partial/lutim.js.ep:89
msgid "Markdown syntax"
msgstr "Syntaxe Markdown"
#: themes/default/templates/partial/myfiles.js.ep:149
msgid "Modify expiration delay"
msgstr "Modifier le délai dexpiration"
#: themes/default/templates/myfiles.html.ep:7 themes/default/templates/partial/navbar.html.ep:18
msgid "My images"
msgstr "Mes images"
#: themes/default/templates/gallery.html.ep:45
msgid "Next (arrow right)"
msgstr "Suivant (flêche droite)"
#: themes/default/templates/partial/myfiles.js.ep:105 themes/default/templates/partial/myfiles.js.ep:132
msgid "No limit"
msgstr "Pas de date dexpiration"
#: themes/default/templates/index.html.ep:183 themes/default/templates/index.html.ep:216
msgid "Only images are allowed"
msgstr "Seules les images sont acceptées"
#: 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 ""
"Seules les images envoyées avec ce navigateur seront listées ici. Les "
"détails sont stockées en localStorage•: si vous supprimez vos données "
"localStorage, vous perdrez ces détails."
#: 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 ""
"Seulement lenvoyeur ! (enfin, seulement sil possède des droits exclusifs "
"sur les images avant de les envoyer)"
#: themes/default/templates/login.html.ep:12
msgid "Password"
msgstr "Mot de passe"
#: themes/default/templates/zip.html.ep:12
msgid "Please click on each URL to download the different zip files."
msgstr ""
"Veuillez cliquer sur chaque URL pour télécharger les différents fichiers zip."
""
#. (config('contact')
#: themes/default/templates/about.html.ep:19
msgid "Please contact the administrator: %1"
msgstr "Veuillez contacter ladministrateur : %1"
#: lib/Lutim/Controller/Authent.pm:36
msgid "Please, check your credentials: unable to authenticate."
msgstr "Veuillez vérifier vos identifiants : impossible de vous authentifier."
#: themes/default/templates/gallery.html.ep:43
msgid "Previous (arrow left)"
msgstr "Précédent (flêche gauche)"
#: 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"
msgstr "Lien vers une image aléatoire"
#: themes/default/templates/stats.html.ep:22
msgid "Raw stats"
msgstr "Statistiques brutes"
#: themes/default/templates/myfiles.html.ep:52
msgid "Save changes"
msgstr "Enregistrer les modifications"
#: themes/default/templates/index.html.ep:176
msgid "Send an image"
msgstr "Envoyer une image"
#: 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 "Connexion"
#: 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"
msgstr "Un problème est survenu"
#. ($c->config('contact')
#: lib/Lutim/Controller/Image.pm:760
msgid ""
"Something went wrong when creating the zip file. Try again later or contact "
"the administrator (%1)."
msgstr ""
"Quelque chose sest mal passé lors de la création de larchive. Veuillez "
"réessayer plus tard ou contactez ladministrateur (%1)."
#: themes/default/templates/partial/navbar.html.ep:55
msgid "Support the author"
msgstr "Supportez lauteur"
#: themes/default/templates/partial/navbar.html.ep:63
msgid "Support the author on Liberapay"
msgstr "Supporter lauteur sur Liberapay"
#: themes/default/templates/partial/navbar.html.ep:60
msgid "Support the author on Tipeee"
msgstr "Supporter lauteur sur Tipeee"
#: 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 ""
"LIP de la personne ayant déposé limage est stockée pendant un délai "
"dépendant de ladministrateur de linstance (pour linstance officielle, "
"dont le serveur est en France, cest un délai\n"
" dun an)."
#: 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 ""
"Le logiciel Lutim est un <a href=\"https://fr.wikipedia.org/wiki/"
"Logiciel_libre\">logiciel libre</a>, ce qui vous permet de le télécharger et "
"de linstaller sur votre propre serveur. Jetez un coup dœil à l<a href="
"\"https://www.gnu.org/licenses/agpl-3.0.html\">AGPL</a> pour voir quels sont "
"vos droits"
#: lib/Lutim/Controller/Image.pm:346
msgid "The URL is not valid."
msgstr "LURL nest pas valide."
#: 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 ""
"Le processus de téléchargement automatique va ouvrir un onglet dans votre "
"navigateur pour chaque lien. Vous devez autoriser les fenêtres popup pour "
"Lutim."
#: themes/default/templates/partial/myfiles.js.ep:32
msgid "The data has been successfully imported."
msgstr "Les données ont été importées avec succès."
#: lib/Lutim/Controller/Image.pm:159 lib/Lutim/Controller/Image.pm:227
msgid "The delete token is invalid."
msgstr "Le jeton de suppression est invalide."
#. ($upload->filename)
#: lib/Lutim/Controller/Image.pm:487
msgid "The file %1 is not an image."
msgstr "Le fichier %1 nest pas une image."
#. ($tx->res->max_message_size)
#. ($c->req->max_message_size)
#. (config('max_file_size')
#: lib/Lutim/Controller/Image.pm:310 lib/Lutim/Controller/Image.pm:379 themes/default/templates/partial/lutim.js.ep:249
msgid "The file exceed the size limit (%1)"
msgstr "Le fichier dépasse la limite de taille (%1)"
#: themes/default/templates/stats.html.ep:12
msgid "The graph's datas are not updated in real-time."
msgstr "Les données du graphique ne sont pas mises à jour en temps réél."
#. ($image->filename)
#: lib/Lutim/Controller/Image.pm:229
msgid "The image %1 has already been deleted."
msgstr "Limage %1 a déjà été supprimée."
#. ($image->filename)
#: lib/Lutim/Controller/Image.pm:238 lib/Lutim/Controller/Image.pm:243
msgid "The image %1 has been successfully deleted"
msgstr "Limage %1 a été supprimée avec succès."
#: lib/Lutim/Controller/Image.pm:167
msgid "The image's delay has been successfully modified"
msgstr "Le délai de limage a été modifié avec succès."
#: themes/default/templates/index.html.ep:63
msgid "The images are encrypted on the server (Lutim does not keep the key)."
msgstr ""
"Les images sont chiffrées sur le serveur (Lutim ne stocke pas la clé)."
#: 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 ""
"Les images déposées sur Lutim peuvent être stockées indéfiniment, ou "
"seffacer dès le premier affichage ou au bout du délai choisi parmi ceux "
"proposés."
#: themes/default/templates/partial/gallery.js.ep:257
msgid "There is XXXX image(s) in the gallery"
msgstr "Il y a XXXX image(s) dans la galerie"
#. ($c->config->{contact})
#: lib/Lutim/Controller/Image.pm:484
msgid "There is no more available URL. Retry or contact the administrator. %1"
msgstr ""
"Il ny a plus dURL disponible. Veuillez réessayer ou contacter "
"ladministrateur. %1."
#: themes/default/templates/gallery.html.ep:30
msgid "Toggle fullscreen"
msgstr "Basculler le plein écran"
#: themes/default/templates/partial/navbar.html.ep:8
msgid "Toggle navigation"
msgstr "Étendre la barre de navigation"
#: lib/Lutim/Command/cron/stats.pm:150 themes/default/templates/raw.html.ep:11
msgid "Total"
msgstr "Total"
#: themes/default/templates/index.html.ep:78 themes/default/templates/partial/lutim.js.ep:17
msgid "Tweet it!"
msgstr "Tweetez !"
#: themes/default/templates/partial/common.js.ep:110 themes/default/templates/partial/common.js.ep:90
msgid "Unable to copy to clipboard"
msgstr "Impossible de copier dans le presse-papier"
#. ($short)
#: lib/Lutim/Controller/Image.pm:107 lib/Lutim/Controller/Image.pm:201 lib/Lutim/Controller/Image.pm:272
msgid "Unable to find the image %1."
msgstr "Impossible de trouver limage %1."
#: lib/Lutim/Controller/Image.pm:573 lib/Lutim/Controller/Image.pm:618 lib/Lutim/Controller/Image.pm:657 lib/Lutim/Controller/Image.pm:700 lib/Lutim/Controller/Image.pm:712 lib/Lutim/Controller/Image.pm:723 lib/Lutim/Controller/Image.pm:750 lib/Lutim/Plugin/Helpers.pm:88
msgid "Unable to find the image: it has been deleted."
msgstr "Impossible de trouver limage : elle a été supprimée."
#: lib/Lutim/Controller/Image.pm:144
msgid "Unable to get counter"
msgstr "Impossible de récupérer le compteur"
#: themes/default/templates/about.html.ep:17
msgid ""
"Unlike many image sharing services, you don't give us rights on uploaded "
"images."
msgstr ""
"Au contraire de la majorité des services de partages dimage, vous ne nous "
"cédez aucun droit sur les images envoyées."
#: themes/default/templates/index.html.ep:180 themes/default/templates/index.html.ep:219
msgid "Upload an image with its URL"
msgstr "Déposer une image par son URL"
#: themes/default/templates/myfiles.html.ep:125
msgid "Uploaded at"
msgstr "Envoyé le"
#: themes/default/templates/stats.html.ep:6
msgid "Uploaded files by days"
msgstr "Fichiers envoyés, par jour"
#. ($c->app->config('contact')
#: lib/Lutim/Plugin/Helpers.pm:221
msgid ""
"Uploading is currently disabled, please try later or contact the "
"administrator (%1)."
msgstr ""
"Lenvoi dimages est actuellement désactivé, veuillez réessayer plus tard ou "
"contacter ladministrateur (%1)."
#: themes/default/templates/index.html.ep:83 themes/default/templates/index.html.ep:85 themes/default/templates/myfiles.html.ep:122 themes/default/templates/partial/lutim.js.ep:72 themes/default/templates/partial/lutim.js.ep:76
msgid "View link"
msgstr "Lien daffichage"
#: themes/default/templates/about.html.ep:22
msgid "What about the software which provides the service?"
msgstr "Et à propos du logiciel qui fournit le service ?"
#: themes/default/templates/about.html.ep:3
msgid "What is Lutim?"
msgstr "Quest-ce que Lutim ?"
#: themes/default/templates/about.html.ep:15
msgid "Who owns rights on images uploaded on Lutim?"
msgstr "Qui possède des droits sur les images envoyées sur Lutim ?"
#: 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 ""
"Oui, ça lest ! Par contre, pour des raisons légales, votre adresse IP sera "
"enregistrée lorsque vous enverrez une image. Ne vous affolez pas, cest de "
"toute façon normalement le cas de tous les sites sur lesquels vous envoyez "
"des fichiers !"
#: 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 ""
"Oui, ça lest ! Par contre, si vous avez envie de soutenir le développeur, "
"vous pouvez faire un microdon avec <a href=\"https://www.tipeee.com/fiat-"
"tux\">Tipeee</a> ou via <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 ""
"Vous avez demandé de télécharger une archive zip pour trop de fichiers."
#: 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 ""
"Vous pouvez, de façon facultative, demander à ce que la ou les images "
"déposées sur Lutim soient supprimées après leur premier affichage (ou "
"téléchargement) ou au bout dun délai choisi parmi ceux proposés."
#: lib/Lutim/Controller/Authent.pm:27
msgid "You have been successfully logged in."
msgstr "Vous avez été connecté·e avec succès."
#: lib/Lutim/Controller/Authent.pm:66 themes/default/templates/logout.html.ep:3
msgid "You have been successfully logged out."
msgstr "Vous avez été déconnecté·e avec succès."
#: themes/default/templates/gallery.html.ep:31
msgid "Zoom in/out"
msgstr "Zoomer / dézoomer"
#: themes/default/templates/about.html.ep:27
msgid "and on"
msgstr "et sur"
#: themes/default/templates/about.html.ep:40
msgid "arabic translation"
msgstr "traduction en arabe"
#: themes/default/templates/about.html.ep:27
msgid "core developer"
msgstr "développeur principal"
#: lib/Lutim.pm:348 lib/Lutim/Command/cron/stats.pm:145 lib/Lutim/Command/cron/stats.pm:159 lib/Lutim/Command/cron/stats.pm:176 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 "Pas de limitation de durée"
#: themes/default/templates/about.html.ep:38
msgid "occitan translation"
msgstr "traduction occitane"
#: themes/default/templates/about.html.ep:27
msgid "on"
msgstr "sur"
#: themes/default/templates/about.html.ep:39
msgid "paste image to upload ability"
msgstr "possibilité de coller une image pour lenvoyer"
#: themes/default/templates/about.html.ep:41
msgid "russian translation"
msgstr "traduction russe"
#: themes/default/templates/about.html.ep:36
msgid "spanish translation"
msgstr "traduction espagnole"
#: themes/default/templates/about.html.ep:28
msgid "webapp developer"
msgstr "développeur de la webapp"

View File

@@ -0,0 +1,696 @@
# Lutim language file
# Copyright (C) 2014 Luc Didry
# This file is distributed under the same license as the Lutim package.
#
# Translators:
# Translators:
# Luc Didry <luc@didry.org>, 2015
# Luc Didry <luc@framasoft.org>, 2018. #zanata
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"PO-Revision-Date: 2018-07-29 08:17+0000\n"
"Last-Translator: Copied by Zanata <copied-by-zanata@zanata.org>\n"
"Language-Team: French (http://www.transifex.com/fiat-tux/lutim/language/fr/)\n"
"Language: fr_FR\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Zanata 4.5.0\n"
#. (7)
#. (30)
#. ($delay)
#. (config('max_delay')
#: lib/Lutim/Command/cron/stats.pm:147 lib/Lutim/Command/cron/stats.pm:148 lib/Lutim/Command/cron/stats.pm:161 lib/Lutim/Command/cron/stats.pm:162 lib/Lutim/Command/cron/stats.pm:178 lib/Lutim/Command/cron/stats.pm:179 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 jours"
#. ($total)
#: themes/default/templates/stats.html.ep:2
msgid "%1 sent images on this instance from beginning."
msgstr "%1 images envoyées sur cette instance depuis le début."
#: themes/default/templates/index.html.ep:208
msgid "-or-"
msgstr "-ou-"
#: lib/Lutim.pm:350 lib/Lutim/Command/cron/stats.pm:149 lib/Lutim/Command/cron/stats.pm:163 lib/Lutim/Command/cron/stats.pm:180 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 an"
#: lib/Lutim.pm:349 lib/Lutim/Command/cron/stats.pm:146 lib/Lutim/Command/cron/stats.pm:160 lib/Lutim/Command/cron/stats.pm:177 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 heures"
#: themes/default/templates/partial/myfiles.js.ep:180
msgid ": Error while trying to get the counter."
msgstr " : Erreur en essayant de récupérer le compteur."
#: themes/default/templates/partial/navbar.html.ep:77
msgid "About"
msgstr "À propos"
#: lib/Lutim/Command/cron/stats.pm:142 themes/default/templates/raw.html.ep:3
msgid "Active images"
msgstr "Images actives"
#: lib/Lutim/Controller/Image.pm:327
msgid "An error occured while downloading the image."
msgstr "Une erreur est survenue lors du téléchargement de limage."
#: themes/default/templates/zip.html.ep:2
msgid "Archives download"
msgstr "Téléchargement darchives"
#: 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"
msgstr "Retour à la page daccueil"
#: themes/default/templates/index.html.ep:211 themes/default/templates/index.html.ep:212
msgid "Click to open the file browser"
msgstr "Cliquez pour utiliser le navigateur de fichier"
#: themes/default/templates/myfiles.html.ep:51
msgid "Close"
msgstr "Fermer"
#: themes/default/templates/gallery.html.ep:29
msgid "Close (Esc)"
msgstr "Fermer (Esc)"
#: themes/default/templates/about.html.ep:30
msgid "Contributors"
msgstr "Contributeurs"
#: themes/default/templates/partial/common.js.ep:113 themes/default/templates/partial/common.js.ep:93
msgid "Copied to clipboard"
msgstr "Copié dans le presse-papier"
#: 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 "Copier tous les liens de visualisation dans le presse-papier"
#: themes/default/templates/index.html.ep:103 themes/default/templates/index.html.ep:111 themes/default/templates/index.html.ep:18 themes/default/templates/index.html.ep:36 themes/default/templates/index.html.ep:54 themes/default/templates/index.html.ep:87 themes/default/templates/index.html.ep:95 themes/default/templates/myfiles.html.ep:104 themes/default/templates/myfiles.html.ep:68 themes/default/templates/myfiles.html.ep:86 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:142
msgid "Copy to clipboard"
msgstr "Copier dans le presse-papier"
#: themes/default/templates/myfiles.html.ep:123
msgid "Counter"
msgstr "Compteur"
#: themes/default/templates/stats.html.ep:18
msgid "Delay repartition chart for disabled images"
msgstr "Graphe de répartition des délais pour les images supprimées"
#: themes/default/templates/stats.html.ep:15
msgid "Delay repartition chart for enabled images"
msgstr "Graphe de répartition des délais pour les images actives"
#: 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?"
msgstr "Supprimer au premier accès ?"
#: lib/Lutim/Command/cron/stats.pm:143 themes/default/templates/raw.html.ep:4
msgid "Deleted images"
msgstr "Images supprimées"
#: lib/Lutim/Command/cron/stats.pm:144 themes/default/templates/raw.html.ep:5
msgid "Deleted images in 30 days"
msgstr "Images supprimées dans 30 jours"
#: themes/default/templates/index.html.ep:116 themes/default/templates/myfiles.html.ep:127 themes/default/templates/partial/common.js.ep:178 themes/default/templates/partial/common.js.ep:181
msgid "Deletion link"
msgstr "Lien de suppression"
#: themes/default/templates/gallery.html.ep:10
msgid "Download all images"
msgstr "Télécharger toutes les images"
#: themes/default/templates/index.html.ep:101 themes/default/templates/index.html.ep:99 themes/default/templates/partial/lutim.js.ep:102 themes/default/templates/partial/lutim.js.ep:98
msgid "Download link"
msgstr "Lien de téléchargement"
#: themes/default/templates/index.html.ep:28 themes/default/templates/index.html.ep:31 themes/default/templates/myfiles.html.ep:78 themes/default/templates/myfiles.html.ep:81
msgid "Download zip link"
msgstr "Lien de téléchargement de larchive des images"
#: themes/default/templates/index.html.ep:207
msgid "Drag & drop images here"
msgstr "Déposez vos images ici"
#: 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 ""
"Faites glisser des images dans la zone prévue à cet effet ou sélectionnez un "
"fichier de façon classique et Lutim vous fournira quatre URLs en retour. Une "
"pour afficher limage, une autre pour la télécharger directement, une pour "
"lutiliser sur les réseaux sociaux et une dernière pour supprimer votre "
"image quand vous le souhaitez"
#: themes/default/templates/index.html.ep:168 themes/default/templates/index.html.ep:199
msgid "Encrypt the image (Lutim does not keep the key)."
msgstr "Chiffrer limage (Lutim ne stocke pas la clé)."
#: 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 "Une erreur est survenue en essayant de modifier limage."
#: themes/default/templates/stats.html.ep:10
msgid "Evolution of total files"
msgstr "Évolution du nombre total de fichiers"
#: themes/default/templates/myfiles.html.ep:126
msgid "Expires at"
msgstr "Expire le"
#: themes/default/templates/myfiles.html.ep:112
msgid "Export localStorage data"
msgstr "Exporter les données localStorage"
#: themes/default/templates/myfiles.html.ep:121
msgid "File name"
msgstr "Nom du fichier"
#: themes/default/templates/about.html.ep:24
msgid ""
"For more details, see the <a href=\"https://framagit.org/luc/"
"lutim\">homepage of the project</a>."
msgstr ""
"Pour plus de détails, consultez la page <a href=\"https://framagit.org/luc/"
"lutim\">Github</a> du projet."
#: themes/default/templates/partial/navbar.html.ep:80
msgid "Fork me!"
msgstr "Créez un fork !"
#: 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"
msgstr "Lien vers la galerie"
#: 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 "Faites Ctrl+C puis appuyez sur la touche Entrée pour copier le lien"
#: themes/default/templates/layouts/default.html.ep:47
msgid "Homepage"
msgstr "Accueil"
#: themes/default/templates/about.html.ep:20
msgid "How do you pronounce Lutim?"
msgstr "Comment doit-on prononcer Lutim ?"
#: themes/default/templates/about.html.ep:6
msgid "How does it work?"
msgstr "Comment ça marche ?"
#: themes/default/templates/about.html.ep:18
msgid "How to report an image?"
msgstr "Comment peut-on faire pour signaler une image ?"
#: 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 ""
"Si les fichiers sont bien supprimés si vous en avez exprimé le choix, leur "
"empreinte SHA512 est toutefois conservée."
#: themes/default/templates/index.html.ep:181 themes/default/templates/index.html.ep:221
msgid "Image URL"
msgstr "URL de limage"
#: lib/Lutim/Command/cron/stats.pm:141 themes/default/templates/raw.html.ep:2
msgid "Image delay"
msgstr "Durée de rétention de limage"
#: themes/default/templates/partial/common.js.ep:157
msgid "Image deleted"
msgstr "Image supprimée"
#: lib/Lutim/Controller/Image.pm:753
msgid "Image not found."
msgstr "Image non trouvée."
#: themes/default/templates/myfiles.html.ep:113
msgid "Import localStorage data"
msgstr "Importer des données localStorage"
#: themes/default/templates/partial/navbar.html.ep:69
msgid "Informations"
msgstr "Informations"
#: themes/default/templates/partial/navbar.html.ep:25
msgid "Install webapp"
msgstr "Installer la webapp"
#: themes/default/templates/partial/navbar.html.ep:21
msgid "Instance's statistics"
msgstr "Statistiques de linstance"
#: themes/default/templates/about.html.ep:11
msgid "Is it really anonymous?"
msgstr "Cest vraiment anonyme ?"
#: themes/default/templates/about.html.ep:9
msgid "Is it really free (as in free beer)?"
msgstr "Cest vraiment gratuit ?"
#: 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 ""
"Comme on prononce <a href=\"https://fr.wikipedia.org/wiki/Lutin\">lutin</a> "
"(/ly.tɛ̃/)."
#: themes/default/templates/index.html.ep:171 themes/default/templates/index.html.ep:202
msgid "Keep EXIF tags"
msgstr "Conserver les données EXIF"
#: themes/default/templates/partial/navbar.html.ep:43
msgid "Language"
msgstr "Langue"
#: themes/default/templates/index.html.ep:136 themes/default/templates/index.html.ep:184 themes/default/templates/index.html.ep:224 themes/default/templates/partial/lutim.js.ep:165
msgid "Let's go!"
msgstr "Allons-y !"
#: themes/default/templates/partial/navbar.html.ep:74
msgid "License:"
msgstr "Licence :"
#: themes/default/templates/index.html.ep:107 themes/default/templates/index.html.ep:109 themes/default/templates/partial/lutim.js.ep:112 themes/default/templates/partial/lutim.js.ep:116
msgid "Link for share on social networks"
msgstr "Lien pour partager sur les réseaux sociaux"
#: themes/default/templates/login.html.ep:8
msgid "Login"
msgstr "Connexion"
#: themes/default/templates/partial/navbar.html.ep:33
msgid "Logout"
msgstr "Déconnexion"
#: 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 peut zipper autant dimages à la fois, votre demande a donc été "
"découpée en plusieurs URL."
#: 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 est un service gratuit et anonyme dhébergement dimages. Il sagit "
"aussi du nom du logiciel (libre) qui fournit ce service."
#: themes/default/templates/about.html.ep:25
msgid "Main developers"
msgstr "Développeurs de lapplication"
#: themes/default/templates/index.html.ep:91 themes/default/templates/index.html.ep:93 themes/default/templates/partial/lutim.js.ep:86 themes/default/templates/partial/lutim.js.ep:89
msgid "Markdown syntax"
msgstr "Syntaxe Markdown"
#: themes/default/templates/partial/myfiles.js.ep:149
msgid "Modify expiration delay"
msgstr "Modifier le délai dexpiration"
#: themes/default/templates/myfiles.html.ep:7 themes/default/templates/partial/navbar.html.ep:18
msgid "My images"
msgstr "Mes images"
#: themes/default/templates/gallery.html.ep:45
msgid "Next (arrow right)"
msgstr "Suivant (flêche droite)"
#: themes/default/templates/partial/myfiles.js.ep:105 themes/default/templates/partial/myfiles.js.ep:132
msgid "No limit"
msgstr "Pas de date dexpiration"
#: themes/default/templates/index.html.ep:183 themes/default/templates/index.html.ep:216
msgid "Only images are allowed"
msgstr "Seules les images sont acceptées"
#: 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 ""
"Seules les images envoyées avec ce navigateur seront listées ici. Les "
"détails sont stockées en localStorage : si vous supprimez vos données "
"localStorage, vous perdrez ces détails."
#: 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 ""
"Seulement lenvoyeur ! (enfin, seulement sil possède des droits exclusifs "
"sur les images avant de les envoyer)"
#: themes/default/templates/login.html.ep:12
msgid "Password"
msgstr "Mot de passe"
#: themes/default/templates/zip.html.ep:12
msgid "Please click on each URL to download the different zip files."
msgstr ""
"Veuillez cliquer sur chaque URL pour télécharger les différents fichiers zip."
""
#. (config('contact')
#: themes/default/templates/about.html.ep:19
msgid "Please contact the administrator: %1"
msgstr "Veuillez contacter ladministrateur : %1"
#: lib/Lutim/Controller/Authent.pm:36
msgid "Please, check your credentials: unable to authenticate."
msgstr "Veuillez vérifier vos identifiants : impossible de vous authentifier."
#: themes/default/templates/gallery.html.ep:43
msgid "Previous (arrow left)"
msgstr "Précédent (flêche gauche)"
#: 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"
msgstr "Lien vers une image aléatoire"
#: themes/default/templates/stats.html.ep:22
msgid "Raw stats"
msgstr "Statistiques brutes"
#: themes/default/templates/myfiles.html.ep:52
msgid "Save changes"
msgstr "Enregistrer les modifications"
#: themes/default/templates/index.html.ep:176
msgid "Send an image"
msgstr "Envoyer une image"
#: 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 "Connexion"
#: 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"
msgstr "Un problème est survenu"
#. ($c->config('contact')
#: lib/Lutim/Controller/Image.pm:760
msgid ""
"Something went wrong when creating the zip file. Try again later or contact "
"the administrator (%1)."
msgstr ""
"Quelque chose sest mal passé lors de la création de larchive. Veuillez "
"réessayer plus tard ou contactez ladministrateur (%1)."
#: themes/default/templates/partial/navbar.html.ep:55
msgid "Support the author"
msgstr "Supportez lauteur"
#: themes/default/templates/partial/navbar.html.ep:63
msgid "Support the author on Liberapay"
msgstr "Supporter lauteur sur Liberapay"
#: themes/default/templates/partial/navbar.html.ep:60
msgid "Support the author on Tipeee"
msgstr "Supporter lauteur sur Tipeee"
#: 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 ""
"LIP de la personne ayant déposé limage est stockée pendant un délai "
"dépendant de ladministrateur de linstance (pour linstance officielle, "
"dont le serveur est en France, cest un délai\n"
" dun an)."
#: 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 ""
"Le logiciel Lutim est un <a href=\"https://fr.wikipedia.org/wiki/"
"Logiciel_libre\">logiciel libre</a>, ce qui vous permet de le télécharger et "
"de linstaller sur votre propre serveur. Jetez un coup dœil à l<a href="
"\"https://www.gnu.org/licenses/agpl-3.0.html\">AGPL</a> pour voir quels sont "
"vos droits"
#: lib/Lutim/Controller/Image.pm:346
msgid "The URL is not valid."
msgstr "LURL nest pas valide."
#: 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 ""
"Le processus de téléchargement automatique va ouvrir un onglet dans votre "
"navigateur pour chaque lien. Vous devez autoriser les fenêtres popup pour "
"Lutim."
#: themes/default/templates/partial/myfiles.js.ep:32
msgid "The data has been successfully imported."
msgstr "Les données ont été importées avec succès."
#: lib/Lutim/Controller/Image.pm:159 lib/Lutim/Controller/Image.pm:227
msgid "The delete token is invalid."
msgstr "Le jeton de suppression est invalide."
#. ($upload->filename)
#: lib/Lutim/Controller/Image.pm:487
msgid "The file %1 is not an image."
msgstr "Le fichier %1 nest pas une image."
#. ($tx->res->max_message_size)
#. ($c->req->max_message_size)
#. (config('max_file_size')
#: lib/Lutim/Controller/Image.pm:310 lib/Lutim/Controller/Image.pm:379 themes/default/templates/partial/lutim.js.ep:249
msgid "The file exceed the size limit (%1)"
msgstr "Le fichier dépasse la limite de taille (%1)"
#: themes/default/templates/stats.html.ep:12
msgid "The graph's datas are not updated in real-time."
msgstr "Les données du graphique ne sont pas mises à jour en temps réél."
#. ($image->filename)
#: lib/Lutim/Controller/Image.pm:229
msgid "The image %1 has already been deleted."
msgstr "Limage %1 a déjà été supprimée."
#. ($image->filename)
#: lib/Lutim/Controller/Image.pm:238 lib/Lutim/Controller/Image.pm:243
msgid "The image %1 has been successfully deleted"
msgstr "Limage %1 a été supprimée avec succès."
#: lib/Lutim/Controller/Image.pm:167
msgid "The image's delay has been successfully modified"
msgstr "Le délai de limage a été modifié avec succès."
#: themes/default/templates/index.html.ep:63
msgid "The images are encrypted on the server (Lutim does not keep the key)."
msgstr ""
"Les images sont chiffrées sur le serveur (Lutim ne stocke pas la clé)."
#: 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 ""
"Les images déposées sur Lutim peuvent être stockées indéfiniment, ou "
"seffacer dès le premier affichage ou au bout du délai choisi parmi ceux "
"proposés."
#: themes/default/templates/partial/gallery.js.ep:257
msgid "There is XXXX image(s) in the gallery"
msgstr "Il y a XXXX image(s) dans la galerie"
#. ($c->config->{contact})
#: lib/Lutim/Controller/Image.pm:484
msgid "There is no more available URL. Retry or contact the administrator. %1"
msgstr ""
"Il ny a plus dURL disponible. Veuillez réessayer ou contacter "
"ladministrateur. %1."
#: themes/default/templates/gallery.html.ep:30
msgid "Toggle fullscreen"
msgstr "Basculler le plein écran"
#: themes/default/templates/partial/navbar.html.ep:8
msgid "Toggle navigation"
msgstr "Étendre la barre de navigation"
#: lib/Lutim/Command/cron/stats.pm:150 themes/default/templates/raw.html.ep:11
msgid "Total"
msgstr "Total"
#: themes/default/templates/index.html.ep:78 themes/default/templates/partial/lutim.js.ep:17
msgid "Tweet it!"
msgstr "Tweetez !"
#: themes/default/templates/partial/common.js.ep:110 themes/default/templates/partial/common.js.ep:90
msgid "Unable to copy to clipboard"
msgstr "Impossible de copier dans le presse-papier"
#. ($short)
#: lib/Lutim/Controller/Image.pm:107 lib/Lutim/Controller/Image.pm:201 lib/Lutim/Controller/Image.pm:272
msgid "Unable to find the image %1."
msgstr "Impossible de trouver limage %1."
#: lib/Lutim/Controller/Image.pm:573 lib/Lutim/Controller/Image.pm:618 lib/Lutim/Controller/Image.pm:657 lib/Lutim/Controller/Image.pm:700 lib/Lutim/Controller/Image.pm:712 lib/Lutim/Controller/Image.pm:723 lib/Lutim/Controller/Image.pm:750 lib/Lutim/Plugin/Helpers.pm:88
msgid "Unable to find the image: it has been deleted."
msgstr "Impossible de trouver limage : elle a été supprimée."
#: lib/Lutim/Controller/Image.pm:144
msgid "Unable to get counter"
msgstr "Impossible de récupérer le compteur"
#: themes/default/templates/about.html.ep:17
msgid ""
"Unlike many image sharing services, you don't give us rights on uploaded "
"images."
msgstr ""
"Au contraire de la majorité des services de partages dimage, vous ne nous "
"cédez aucun droit sur les images envoyées."
#: themes/default/templates/index.html.ep:180 themes/default/templates/index.html.ep:219
msgid "Upload an image with its URL"
msgstr "Déposer une image par son URL"
#: themes/default/templates/myfiles.html.ep:125
msgid "Uploaded at"
msgstr "Envoyé le"
#: themes/default/templates/stats.html.ep:6
msgid "Uploaded files by days"
msgstr "Fichiers envoyés, par jour"
#. ($c->app->config('contact')
#: lib/Lutim/Plugin/Helpers.pm:221
msgid ""
"Uploading is currently disabled, please try later or contact the "
"administrator (%1)."
msgstr ""
"Lenvoi dimages est actuellement désactivé, veuillez réessayer plus tard ou "
"contacter ladministrateur (%1)."
#: themes/default/templates/index.html.ep:83 themes/default/templates/index.html.ep:85 themes/default/templates/myfiles.html.ep:122 themes/default/templates/partial/lutim.js.ep:72 themes/default/templates/partial/lutim.js.ep:76
msgid "View link"
msgstr "Lien daffichage"
#: themes/default/templates/about.html.ep:22
msgid "What about the software which provides the service?"
msgstr "Et à propos du logiciel qui fournit le service ?"
#: themes/default/templates/about.html.ep:3
msgid "What is Lutim?"
msgstr "Quest-ce que Lutim ?"
#: themes/default/templates/about.html.ep:15
msgid "Who owns rights on images uploaded on Lutim?"
msgstr "Qui possède des droits sur les images envoyées sur Lutim ?"
#: 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 ""
"Oui, ça lest ! Par contre, pour des raisons légales, votre adresse IP sera "
"enregistrée lorsque vous enverrez une image. Ne vous affolez pas, cest de "
"toute façon normalement le cas de tous les sites sur lesquels vous envoyez "
"des fichiers !"
#: 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 ""
"Oui, ça lest ! Par contre, si vous avez envie de soutenir le développeur, "
"vous pouvez faire un microdon avec <a href=\"https://www.tipeee.com/fiat-"
"tux\">Tipeee</a> ou via <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 ""
"Vous avez demandé de télécharger une archive zip pour trop de fichiers."
#: 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 ""
"Vous pouvez, de façon facultative, demander à ce que la ou les images "
"déposées sur Lutim soient supprimées après leur premier affichage (ou "
"téléchargement) ou au bout dun délai choisi parmi ceux proposés."
#: lib/Lutim/Controller/Authent.pm:27
msgid "You have been successfully logged in."
msgstr "Vous avez été connecté·e avec succès."
#: lib/Lutim/Controller/Authent.pm:66 themes/default/templates/logout.html.ep:3
msgid "You have been successfully logged out."
msgstr "Vous avez été déconnecté·e avec succès."
#: themes/default/templates/gallery.html.ep:31
msgid "Zoom in/out"
msgstr "Zoomer / dézoomer"
#: themes/default/templates/about.html.ep:27
msgid "and on"
msgstr "et sur"
#: themes/default/templates/about.html.ep:40
msgid "arabic translation"
msgstr "traduction en arabe"
#: themes/default/templates/about.html.ep:27
msgid "core developer"
msgstr "développeur principal"
#: lib/Lutim.pm:348 lib/Lutim/Command/cron/stats.pm:145 lib/Lutim/Command/cron/stats.pm:159 lib/Lutim/Command/cron/stats.pm:176 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 "Pas de limitation de durée"
#: themes/default/templates/about.html.ep:38
msgid "occitan translation"
msgstr "traduction occitane"
#: themes/default/templates/about.html.ep:27
msgid "on"
msgstr "sur"
#: themes/default/templates/about.html.ep:39
msgid "paste image to upload ability"
msgstr "possibilité de coller une image pour lenvoyer"
#: themes/default/templates/about.html.ep:41
msgid "russian translation"
msgstr "traduction russe"
#: themes/default/templates/about.html.ep:36
msgid "spanish translation"
msgstr "traduction espagnole"
#: themes/default/templates/about.html.ep:28
msgid "webapp developer"
msgstr "développeur de la webapp"

View File

@@ -0,0 +1,641 @@
# Meskó Balázs <mesko.balazs@fsf.hu>, 2018. #zanata
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"PO-Revision-Date: 2018-06-01 09:17+0000\n"
"Last-Translator: Meskó Balázs <mesko.balazs@fsf.hu>\n"
"Language-Team: Hungarian\n"
"Language: hu\n"
"X-Generator: Zanata 4.5.0\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#. (7)
#. (30)
#. ($delay)
#. (config('max_delay')
#: lib/Lutim/Command/cron/stats.pm:147 lib/Lutim/Command/cron/stats.pm:148 lib/Lutim/Command/cron/stats.pm:161 lib/Lutim/Command/cron/stats.pm:162 lib/Lutim/Command/cron/stats.pm:178 lib/Lutim/Command/cron/stats.pm:179 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 nap"
#. ($total)
#: themes/default/templates/stats.html.ep:2
msgid "%1 sent images on this instance from beginning."
msgstr ""
#: themes/default/templates/index.html.ep:208
msgid "-or-"
msgstr ""
#: lib/Lutim.pm:350 lib/Lutim/Command/cron/stats.pm:149 lib/Lutim/Command/cron/stats.pm:163 lib/Lutim/Command/cron/stats.pm:180 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 év"
#: lib/Lutim.pm:349 lib/Lutim/Command/cron/stats.pm:146 lib/Lutim/Command/cron/stats.pm:160 lib/Lutim/Command/cron/stats.pm:177 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 óra"
#: themes/default/templates/partial/myfiles.js.ep:180
msgid ": Error while trying to get the counter."
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:77
msgid "About"
msgstr "Névjegy"
#: lib/Lutim/Command/cron/stats.pm:142 themes/default/templates/raw.html.ep:3
msgid "Active images"
msgstr "Aktív képek"
#: lib/Lutim/Controller/Image.pm:327
msgid "An error occured while downloading the image."
msgstr "Hiba történt a kép letöltése közben"
#: themes/default/templates/zip.html.ep:2
msgid "Archives download"
msgstr "Archívum letöltése"
#: 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"
msgstr "Vissza a kezdőoldalra"
#: themes/default/templates/index.html.ep:211 themes/default/templates/index.html.ep:212
msgid "Click to open the file browser"
msgstr "Kattints a fájlböngésző megnyitásához"
#: themes/default/templates/myfiles.html.ep:51
msgid "Close"
msgstr ""
#: themes/default/templates/gallery.html.ep:29
msgid "Close (Esc)"
msgstr "Bezárás (Esc)"
#: themes/default/templates/about.html.ep:30
msgid "Contributors"
msgstr "Közreműködők"
#: themes/default/templates/partial/common.js.ep:113 themes/default/templates/partial/common.js.ep:93
msgid "Copied to clipboard"
msgstr ""
#: 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 "Összes megtekintési hivatkozás másolása a vágólapra"
#: themes/default/templates/index.html.ep:103 themes/default/templates/index.html.ep:111 themes/default/templates/index.html.ep:18 themes/default/templates/index.html.ep:36 themes/default/templates/index.html.ep:54 themes/default/templates/index.html.ep:87 themes/default/templates/index.html.ep:95 themes/default/templates/myfiles.html.ep:104 themes/default/templates/myfiles.html.ep:68 themes/default/templates/myfiles.html.ep:86 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:142
msgid "Copy to clipboard"
msgstr "Másolás a vágólapra"
#: themes/default/templates/myfiles.html.ep:123
msgid "Counter"
msgstr "Számláló"
#: themes/default/templates/stats.html.ep:18
msgid "Delay repartition chart for disabled images"
msgstr ""
#: themes/default/templates/stats.html.ep:15
msgid "Delay repartition chart for enabled images"
msgstr ""
#: 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?"
msgstr "Törlés az első megtekintés után?"
#: lib/Lutim/Command/cron/stats.pm:143 themes/default/templates/raw.html.ep:4
msgid "Deleted images"
msgstr "Törölt képek"
#: lib/Lutim/Command/cron/stats.pm:144 themes/default/templates/raw.html.ep:5
msgid "Deleted images in 30 days"
msgstr "Törölt képek 30 napban"
#: themes/default/templates/index.html.ep:116 themes/default/templates/myfiles.html.ep:127 themes/default/templates/partial/common.js.ep:178 themes/default/templates/partial/common.js.ep:181
msgid "Deletion link"
msgstr "Törlési hivatkozás"
#: themes/default/templates/gallery.html.ep:10
msgid "Download all images"
msgstr "Összes kép letöltése"
#: themes/default/templates/index.html.ep:101 themes/default/templates/index.html.ep:99 themes/default/templates/partial/lutim.js.ep:102 themes/default/templates/partial/lutim.js.ep:98
msgid "Download link"
msgstr "Letöltési hivatkozás"
#: themes/default/templates/index.html.ep:28 themes/default/templates/index.html.ep:31 themes/default/templates/myfiles.html.ep:78 themes/default/templates/myfiles.html.ep:81
msgid "Download zip link"
msgstr "Zip letöltési hivatkozás"
#: themes/default/templates/index.html.ep:207
msgid "Drag & drop images here"
msgstr "Húzd és ejtsd ide a képeket"
#: 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 ""
#: themes/default/templates/index.html.ep:168 themes/default/templates/index.html.ep:199
msgid "Encrypt the image (Lutim does not keep the key)."
msgstr "Kép titkosítása (A Lutim nem tartja meg a kulcsot)."
#: 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 "Hiba történt a kép módosításakor."
#: themes/default/templates/stats.html.ep:10
msgid "Evolution of total files"
msgstr "Az összes fájl evolúciója"
#: themes/default/templates/myfiles.html.ep:126
msgid "Expires at"
msgstr "Lejárat:"
#: themes/default/templates/myfiles.html.ep:112
msgid "Export localStorage data"
msgstr ""
#: themes/default/templates/myfiles.html.ep:121
msgid "File name"
msgstr "Fájlnév"
#: themes/default/templates/about.html.ep:24
msgid ""
"For more details, see the <a href=\"https://framagit.org/luc/"
"lutim\">homepage of the project</a>."
msgstr ""
"További részletekért lásd a <a href=\"https://framagit.org/luc/"
"lutim\">projekt weboldalát</a>."
#: themes/default/templates/partial/navbar.html.ep:80
msgid "Fork me!"
msgstr "Forkolj le!"
#: 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"
msgstr "Galéria hivatkozás"
#: 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 ""
#: themes/default/templates/layouts/default.html.ep:47
msgid "Homepage"
msgstr "Kezdőlap"
#: themes/default/templates/about.html.ep:20
msgid "How do you pronounce Lutim?"
msgstr "Hogyan ejtem ki, hogy Lutim?"
#: themes/default/templates/about.html.ep:6
msgid "How does it work?"
msgstr "Hogyan működik?"
#: themes/default/templates/about.html.ep:18
msgid "How to report an image?"
msgstr "Hogyan jelentsek egy képet?"
#: 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 ""
#: themes/default/templates/index.html.ep:181 themes/default/templates/index.html.ep:221
msgid "Image URL"
msgstr "Kép URL"
#: lib/Lutim/Command/cron/stats.pm:141 themes/default/templates/raw.html.ep:2
msgid "Image delay"
msgstr ""
#: themes/default/templates/partial/common.js.ep:157
msgid "Image deleted"
msgstr ""
#: lib/Lutim/Controller/Image.pm:753
msgid "Image not found."
msgstr "A kép nem található."
#: themes/default/templates/myfiles.html.ep:113
msgid "Import localStorage data"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:69
msgid "Informations"
msgstr "Információk"
#: themes/default/templates/partial/navbar.html.ep:25
msgid "Install webapp"
msgstr "Webalkalmazás telepítése"
#: themes/default/templates/partial/navbar.html.ep:21
msgid "Instance's statistics"
msgstr "Példány statisztikái"
#: themes/default/templates/about.html.ep:11
msgid "Is it really anonymous?"
msgstr "Tényleg anonim?"
#: themes/default/templates/about.html.ep:9
msgid "Is it really free (as in free beer)?"
msgstr "Tényleg ingyenes?"
#: 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 ""
"Pont úgy, ahogy a francia <a href=\"https://fr.wikipedia.org/wiki/"
"Lutin\">lutin</a> szót (/ly.tɛ̃/)."
#: themes/default/templates/index.html.ep:171 themes/default/templates/index.html.ep:202
msgid "Keep EXIF tags"
msgstr "EXIF címkék megtartása"
#: themes/default/templates/partial/navbar.html.ep:43
msgid "Language"
msgstr "Nyelv"
#: themes/default/templates/index.html.ep:136 themes/default/templates/index.html.ep:184 themes/default/templates/index.html.ep:224 themes/default/templates/partial/lutim.js.ep:165
msgid "Let's go!"
msgstr "Gyerünk!"
#: themes/default/templates/partial/navbar.html.ep:74
msgid "License:"
msgstr "Licenc:"
#: themes/default/templates/index.html.ep:107 themes/default/templates/index.html.ep:109 themes/default/templates/partial/lutim.js.ep:112 themes/default/templates/partial/lutim.js.ep:116
msgid "Link for share on social networks"
msgstr "Közösségi média megosztási hivatkozások"
#: themes/default/templates/login.html.ep:8
msgid "Login"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:33
msgid "Logout"
msgstr ""
#: 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 ""
#: 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 ""
#: themes/default/templates/about.html.ep:25
msgid "Main developers"
msgstr "Fő fejlesztők"
#: themes/default/templates/index.html.ep:91 themes/default/templates/index.html.ep:93 themes/default/templates/partial/lutim.js.ep:86 themes/default/templates/partial/lutim.js.ep:89
msgid "Markdown syntax"
msgstr "Markdown szintaxis"
#: themes/default/templates/partial/myfiles.js.ep:149
msgid "Modify expiration delay"
msgstr ""
#: themes/default/templates/myfiles.html.ep:7 themes/default/templates/partial/navbar.html.ep:18
msgid "My images"
msgstr "Saját képek"
#: themes/default/templates/gallery.html.ep:45
msgid "Next (arrow right)"
msgstr "Következő (jobbra nyíl)"
#: themes/default/templates/partial/myfiles.js.ep:105 themes/default/templates/partial/myfiles.js.ep:132
msgid "No limit"
msgstr "Nincs korlát"
#: themes/default/templates/index.html.ep:183 themes/default/templates/index.html.ep:216
msgid "Only images are allowed"
msgstr "Csak képek engedélyezettek"
#: 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 ""
#: 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 ""
"Csak a feltöltő! (persze csak akkor, ha az övé a két összes joga a "
"feltöltéskor)"
#: themes/default/templates/login.html.ep:12
msgid "Password"
msgstr ""
#: themes/default/templates/zip.html.ep:12
msgid "Please click on each URL to download the different zip files."
msgstr ""
#. (config('contact')
#: themes/default/templates/about.html.ep:19
msgid "Please contact the administrator: %1"
msgstr "Vedd fel a kapcsolatot az adminisztrátorral: %1"
#: lib/Lutim/Controller/Authent.pm:36
msgid "Please, check your credentials: unable to authenticate."
msgstr ""
#: themes/default/templates/gallery.html.ep:43
msgid "Previous (arrow left)"
msgstr "Előző (balra nyíl)"
#: 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"
msgstr ""
#: themes/default/templates/stats.html.ep:22
msgid "Raw stats"
msgstr "Nyers statisztikák"
#: themes/default/templates/myfiles.html.ep:52
msgid "Save changes"
msgstr ""
#: themes/default/templates/index.html.ep:176
msgid "Send an image"
msgstr "Kép küldése"
#: 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 ""
#: 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"
msgstr "Valami rossz történt"
#. ($c->config('contact')
#: lib/Lutim/Controller/Image.pm:760
msgid ""
"Something went wrong when creating the zip file. Try again later or contact "
"the administrator (%1)."
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:55
msgid "Support the author"
msgstr "A szerző támogatása"
#: themes/default/templates/partial/navbar.html.ep:63
msgid "Support the author on Liberapay"
msgstr "A szerző támogatása a Liberapayen"
#: themes/default/templates/partial/navbar.html.ep:60
msgid "Support the author on Tipeee"
msgstr "A szerző támogatása a Tipeee-n"
#: 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 ""
#: 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 ""
"A Lutim szoftver <a href=\"http://en.wikipedia.org/wiki/"
"Free_software\">szabad szoftver</a>, így letöltheted és telepítheted a saját "
"kiszolgálódra. Nézd meg az <a href=\"https://www.gnu.org/licenses/agpl-3.0."
"html\">AGPL-t</a>, hogy megtudd mit tehetsz."
#: lib/Lutim/Controller/Image.pm:346
msgid "The URL is not valid."
msgstr "Az URL érvénytelen."
#: 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 ""
#: themes/default/templates/partial/myfiles.js.ep:32
msgid "The data has been successfully imported."
msgstr ""
#: lib/Lutim/Controller/Image.pm:159 lib/Lutim/Controller/Image.pm:227
msgid "The delete token is invalid."
msgstr "A törlési token érvénytelen."
#. ($upload->filename)
#: lib/Lutim/Controller/Image.pm:487
msgid "The file %1 is not an image."
msgstr "A(z) %1 fájl nem kép."
#. ($tx->res->max_message_size)
#. ($c->req->max_message_size)
#. (config('max_file_size')
#: lib/Lutim/Controller/Image.pm:310 lib/Lutim/Controller/Image.pm:379 themes/default/templates/partial/lutim.js.ep:249
msgid "The file exceed the size limit (%1)"
msgstr "A fájl meghaladja a méretkorlátot (%1)"
#: themes/default/templates/stats.html.ep:12
msgid "The graph's datas are not updated in real-time."
msgstr "A grafikon adatai nem frissülnek valós időben."
#. ($image->filename)
#: lib/Lutim/Controller/Image.pm:229
msgid "The image %1 has already been deleted."
msgstr "A(z) %1 kép már törölve lett."
#. ($image->filename)
#: lib/Lutim/Controller/Image.pm:238 lib/Lutim/Controller/Image.pm:243
msgid "The image %1 has been successfully deleted"
msgstr "A(z) %1 kép sikeresen törölve lett"
#: lib/Lutim/Controller/Image.pm:167
msgid "The image's delay has been successfully modified"
msgstr ""
#: themes/default/templates/index.html.ep:63
msgid "The images are encrypted on the server (Lutim does not keep the key)."
msgstr ""
#: 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 ""
#: themes/default/templates/partial/gallery.js.ep:257
msgid "There is XXXX image(s) in the gallery"
msgstr ""
#. ($c->config->{contact})
#: lib/Lutim/Controller/Image.pm:484
msgid "There is no more available URL. Retry or contact the administrator. %1"
msgstr ""
#: themes/default/templates/gallery.html.ep:30
msgid "Toggle fullscreen"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:8
msgid "Toggle navigation"
msgstr ""
#: lib/Lutim/Command/cron/stats.pm:150 themes/default/templates/raw.html.ep:11
msgid "Total"
msgstr ""
#: themes/default/templates/index.html.ep:78 themes/default/templates/partial/lutim.js.ep:17
msgid "Tweet it!"
msgstr ""
#: themes/default/templates/partial/common.js.ep:110 themes/default/templates/partial/common.js.ep:90
msgid "Unable to copy to clipboard"
msgstr ""
#. ($short)
#: lib/Lutim/Controller/Image.pm:107 lib/Lutim/Controller/Image.pm:201 lib/Lutim/Controller/Image.pm:272
msgid "Unable to find the image %1."
msgstr ""
#: lib/Lutim/Controller/Image.pm:573 lib/Lutim/Controller/Image.pm:618 lib/Lutim/Controller/Image.pm:657 lib/Lutim/Controller/Image.pm:700 lib/Lutim/Controller/Image.pm:712 lib/Lutim/Controller/Image.pm:723 lib/Lutim/Controller/Image.pm:750 lib/Lutim/Plugin/Helpers.pm:88
msgid "Unable to find the image: it has been deleted."
msgstr ""
#: lib/Lutim/Controller/Image.pm:144
msgid "Unable to get counter"
msgstr ""
#: themes/default/templates/about.html.ep:17
msgid ""
"Unlike many image sharing services, you don't give us rights on uploaded "
"images."
msgstr ""
#: themes/default/templates/index.html.ep:180 themes/default/templates/index.html.ep:219
msgid "Upload an image with its URL"
msgstr ""
#: themes/default/templates/myfiles.html.ep:125
msgid "Uploaded at"
msgstr ""
#: themes/default/templates/stats.html.ep:6
msgid "Uploaded files by days"
msgstr ""
#. ($c->app->config('contact')
#: lib/Lutim/Plugin/Helpers.pm:221
msgid ""
"Uploading is currently disabled, please try later or contact the "
"administrator (%1)."
msgstr ""
#: themes/default/templates/index.html.ep:83 themes/default/templates/index.html.ep:85 themes/default/templates/myfiles.html.ep:122 themes/default/templates/partial/lutim.js.ep:72 themes/default/templates/partial/lutim.js.ep:76
msgid "View link"
msgstr ""
#: themes/default/templates/about.html.ep:22
msgid "What about the software which provides the service?"
msgstr ""
#: themes/default/templates/about.html.ep:3
msgid "What is Lutim?"
msgstr ""
#: themes/default/templates/about.html.ep:15
msgid "Who owns rights on images uploaded on Lutim?"
msgstr ""
#: 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 ""
#: 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 ""
#: themes/default/templates/zip.html.ep:6
msgid "You asked to download a zip archive for too much files."
msgstr ""
#: 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 ""
#: lib/Lutim/Controller/Authent.pm:27
msgid "You have been successfully logged in."
msgstr ""
#: lib/Lutim/Controller/Authent.pm:66 themes/default/templates/logout.html.ep:3
msgid "You have been successfully logged out."
msgstr ""
#: themes/default/templates/gallery.html.ep:31
msgid "Zoom in/out"
msgstr ""
#: themes/default/templates/about.html.ep:27
msgid "and on"
msgstr ""
#: themes/default/templates/about.html.ep:40
msgid "arabic translation"
msgstr ""
#: themes/default/templates/about.html.ep:27
msgid "core developer"
msgstr ""
#: lib/Lutim.pm:348 lib/Lutim/Command/cron/stats.pm:145 lib/Lutim/Command/cron/stats.pm:159 lib/Lutim/Command/cron/stats.pm:176 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 ""
#: themes/default/templates/about.html.ep:38
msgid "occitan translation"
msgstr ""
#: themes/default/templates/about.html.ep:27
msgid "on"
msgstr ""
#: themes/default/templates/about.html.ep:39
msgid "paste image to upload ability"
msgstr ""
#: themes/default/templates/about.html.ep:41
msgid "russian translation"
msgstr ""
#: themes/default/templates/about.html.ep:36
msgid "spanish translation"
msgstr ""
#: themes/default/templates/about.html.ep:28
msgid "webapp developer"
msgstr ""

View File

@@ -0,0 +1,588 @@
# 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.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#. (7)
#. (30)
#. ($delay)
#. (config('max_delay')
#: lib/Lutim/Command/cron/stats.pm:159 lib/Lutim/Command/cron/stats.pm:160 lib/Lutim/Command/cron/stats.pm:173 lib/Lutim/Command/cron/stats.pm:174 lib/Lutim/Command/cron/stats.pm:190 lib/Lutim/Command/cron/stats.pm:191 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 ""
#. ($total)
#: themes/default/templates/stats.html.ep:2
msgid "%1 sent images on this instance from beginning."
msgstr ""
#: themes/default/templates/index.html.ep:208
msgid "-or-"
msgstr ""
#: lib/Lutim.pm:350 lib/Lutim/Command/cron/stats.pm:161 lib/Lutim/Command/cron/stats.pm:175 lib/Lutim/Command/cron/stats.pm:192 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 ""
#: lib/Lutim.pm:349 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: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 ""
#: themes/default/templates/partial/myfiles.js.ep:180
msgid ": Error while trying to get the counter."
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:77
msgid "About"
msgstr ""
#: lib/Lutim/Command/cron/stats.pm:154 themes/default/templates/raw.html.ep:3
msgid "Active images"
msgstr ""
#: lib/Lutim/Controller/Image.pm:328
msgid "An error occured while downloading the image."
msgstr ""
#: themes/default/templates/zip.html.ep:2
msgid "Archives download"
msgstr ""
#: 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"
msgstr ""
#: themes/default/templates/index.html.ep:211 themes/default/templates/index.html.ep:212
msgid "Click to open the file browser"
msgstr ""
#: themes/default/templates/myfiles.html.ep:51
msgid "Close"
msgstr ""
#: themes/default/templates/gallery.html.ep:29
msgid "Close (Esc)"
msgstr ""
#: themes/default/templates/about.html.ep:30
msgid "Contributors"
msgstr ""
#: themes/default/templates/partial/common.js.ep:113 themes/default/templates/partial/common.js.ep:93
msgid "Copied to clipboard"
msgstr ""
#: 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 ""
#: themes/default/templates/index.html.ep:103 themes/default/templates/index.html.ep:111 themes/default/templates/index.html.ep:18 themes/default/templates/index.html.ep:36 themes/default/templates/index.html.ep:54 themes/default/templates/index.html.ep:87 themes/default/templates/index.html.ep:95 themes/default/templates/myfiles.html.ep:104 themes/default/templates/myfiles.html.ep:68 themes/default/templates/myfiles.html.ep:86 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:142
msgid "Copy to clipboard"
msgstr ""
#: themes/default/templates/myfiles.html.ep:123
msgid "Counter"
msgstr ""
#: themes/default/templates/stats.html.ep:18
msgid "Delay repartition chart for disabled images"
msgstr ""
#: themes/default/templates/stats.html.ep:15
msgid "Delay repartition chart for enabled images"
msgstr ""
#: 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?"
msgstr ""
#: lib/Lutim/Command/cron/stats.pm:155 themes/default/templates/raw.html.ep:4
msgid "Deleted images"
msgstr ""
#: lib/Lutim/Command/cron/stats.pm:156 themes/default/templates/raw.html.ep:5
msgid "Deleted images in 30 days"
msgstr ""
#: themes/default/templates/index.html.ep:116 themes/default/templates/myfiles.html.ep:127 themes/default/templates/partial/common.js.ep:178 themes/default/templates/partial/common.js.ep:181
msgid "Deletion link"
msgstr ""
#: themes/default/templates/gallery.html.ep:10
msgid "Download all images"
msgstr ""
#: themes/default/templates/index.html.ep:101 themes/default/templates/index.html.ep:99 themes/default/templates/partial/lutim.js.ep:102 themes/default/templates/partial/lutim.js.ep:98
msgid "Download link"
msgstr ""
#: themes/default/templates/index.html.ep:28 themes/default/templates/index.html.ep:31 themes/default/templates/myfiles.html.ep:78 themes/default/templates/myfiles.html.ep:81
msgid "Download zip link"
msgstr ""
#: themes/default/templates/index.html.ep:207
msgid "Drag & drop images here"
msgstr ""
#: 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 ""
#: themes/default/templates/index.html.ep:168 themes/default/templates/index.html.ep:199
msgid "Encrypt the image (Lutim does not keep the key)."
msgstr ""
#: 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 ""
#: themes/default/templates/stats.html.ep:10
msgid "Evolution of total files"
msgstr ""
#: themes/default/templates/myfiles.html.ep:126
msgid "Expires at"
msgstr ""
#: themes/default/templates/myfiles.html.ep:112
msgid "Export localStorage data"
msgstr ""
#: themes/default/templates/myfiles.html.ep:121
msgid "File name"
msgstr ""
#: themes/default/templates/about.html.ep:24
msgid "For more details, see the <a href=\"https://framagit.org/luc/lutim\">homepage of the project</a>."
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:80
msgid "Fork me!"
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"
msgstr ""
#: 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 ""
#: themes/default/templates/layouts/default.html.ep:47
msgid "Homepage"
msgstr ""
#: themes/default/templates/about.html.ep:20
msgid "How do you pronounce Lutim?"
msgstr ""
#: themes/default/templates/about.html.ep:6
msgid "How does it work?"
msgstr ""
#: themes/default/templates/about.html.ep:18
msgid "How to report an image?"
msgstr ""
#: 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 ""
#: themes/default/templates/index.html.ep:181 themes/default/templates/index.html.ep:221
msgid "Image URL"
msgstr ""
#: lib/Lutim/Command/cron/stats.pm:153 themes/default/templates/raw.html.ep:2
msgid "Image delay"
msgstr ""
#: themes/default/templates/partial/common.js.ep:157
msgid "Image deleted"
msgstr ""
#: lib/Lutim/Controller/Image.pm:756
msgid "Image not found."
msgstr ""
#: themes/default/templates/myfiles.html.ep:113
msgid "Import localStorage data"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:69
msgid "Informations"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:25
msgid "Install webapp"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:21
msgid "Instance's statistics"
msgstr ""
#: themes/default/templates/about.html.ep:11
msgid "Is it really anonymous?"
msgstr ""
#: themes/default/templates/about.html.ep:9
msgid "Is it really free (as in free beer)?"
msgstr ""
#: 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 ""
#: themes/default/templates/index.html.ep:171 themes/default/templates/index.html.ep:202
msgid "Keep EXIF tags"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:43
msgid "Language"
msgstr ""
#: themes/default/templates/index.html.ep:136 themes/default/templates/index.html.ep:184 themes/default/templates/index.html.ep:224 themes/default/templates/partial/lutim.js.ep:165
msgid "Let's go!"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:74
msgid "License:"
msgstr ""
#: themes/default/templates/index.html.ep:107 themes/default/templates/index.html.ep:109 themes/default/templates/partial/lutim.js.ep:112 themes/default/templates/partial/lutim.js.ep:116
msgid "Link for share on social networks"
msgstr ""
#: themes/default/templates/login.html.ep:8
msgid "Login"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:33
msgid "Logout"
msgstr ""
#: 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 ""
#: 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 ""
#: themes/default/templates/about.html.ep:25
msgid "Main developers"
msgstr ""
#: themes/default/templates/index.html.ep:91 themes/default/templates/index.html.ep:93 themes/default/templates/partial/lutim.js.ep:86 themes/default/templates/partial/lutim.js.ep:89
msgid "Markdown syntax"
msgstr ""
#: themes/default/templates/partial/myfiles.js.ep:149
msgid "Modify expiration delay"
msgstr ""
#: themes/default/templates/myfiles.html.ep:7 themes/default/templates/partial/navbar.html.ep:18
msgid "My images"
msgstr ""
#: themes/default/templates/gallery.html.ep:45
msgid "Next (arrow right)"
msgstr ""
#: themes/default/templates/partial/myfiles.js.ep:105 themes/default/templates/partial/myfiles.js.ep:132
msgid "No limit"
msgstr ""
#: themes/default/templates/index.html.ep:183 themes/default/templates/index.html.ep:216
msgid "Only images are allowed"
msgstr ""
#: 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 ""
#: 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 ""
#: themes/default/templates/login.html.ep:12
msgid "Password"
msgstr ""
#: themes/default/templates/zip.html.ep:12
msgid "Please click on each URL to download the different zip files."
msgstr ""
#. (config('contact')
#: themes/default/templates/about.html.ep:19
msgid "Please contact the administrator: %1"
msgstr ""
#: lib/Lutim/Controller/Authent.pm:36
msgid "Please, check your credentials: unable to authenticate."
msgstr ""
#: themes/default/templates/gallery.html.ep:43
msgid "Previous (arrow left)"
msgstr ""
#: 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"
msgstr ""
#: themes/default/templates/stats.html.ep:22
msgid "Raw stats"
msgstr ""
#: themes/default/templates/myfiles.html.ep:52
msgid "Save changes"
msgstr ""
#: themes/default/templates/index.html.ep:176
msgid "Send an image"
msgstr ""
#: 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 ""
#: 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"
msgstr ""
#. ($c->config('contact')
#: lib/Lutim/Controller/Image.pm:763
msgid "Something went wrong when creating the zip file. Try again later or contact the administrator (%1)."
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:55
msgid "Support the author"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:63
msgid "Support the author on Liberapay"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:60
msgid "Support the author on Tipeee"
msgstr ""
#: 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 ""
#: 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 ""
#: lib/Lutim/Controller/Image.pm:347
msgid "The URL is not valid."
msgstr ""
#: 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 ""
#: themes/default/templates/partial/myfiles.js.ep:32
msgid "The data has been successfully imported."
msgstr ""
#: lib/Lutim/Controller/Image.pm:160 lib/Lutim/Controller/Image.pm:228
msgid "The delete token is invalid."
msgstr ""
#. ($upload->filename)
#: lib/Lutim/Controller/Image.pm:488
msgid "The file %1 is not an image."
msgstr ""
#. ($tx->res->max_message_size)
#. ($c->req->max_message_size)
#. (config('max_file_size')
#: lib/Lutim/Controller/Image.pm:311 lib/Lutim/Controller/Image.pm:380 themes/default/templates/partial/lutim.js.ep:249
msgid "The file exceed the size limit (%1)"
msgstr ""
#: themes/default/templates/stats.html.ep:12
msgid "The graph's datas are not updated in real-time."
msgstr ""
#. ($image->filename)
#: lib/Lutim/Controller/Image.pm:230
msgid "The image %1 has already been deleted."
msgstr ""
#. ($image->filename)
#: lib/Lutim/Controller/Image.pm:239 lib/Lutim/Controller/Image.pm:244
msgid "The image %1 has been successfully deleted"
msgstr ""
#: lib/Lutim/Controller/Image.pm:168
msgid "The image's delay has been successfully modified"
msgstr ""
#: themes/default/templates/index.html.ep:63
msgid "The images are encrypted on the server (Lutim does not keep the key)."
msgstr ""
#: 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 ""
#: themes/default/templates/partial/gallery.js.ep:257
msgid "There is XXXX image(s) in the gallery"
msgstr ""
#. ($c->config->{contact})
#: lib/Lutim/Controller/Image.pm:485
msgid "There is no more available URL. Retry or contact the administrator. %1"
msgstr ""
#: themes/default/templates/gallery.html.ep:30
msgid "Toggle fullscreen"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:8
msgid "Toggle navigation"
msgstr ""
#: lib/Lutim/Command/cron/stats.pm:162 themes/default/templates/raw.html.ep:11
msgid "Total"
msgstr ""
#: themes/default/templates/index.html.ep:78 themes/default/templates/partial/lutim.js.ep:17
msgid "Tweet it!"
msgstr ""
#: themes/default/templates/partial/common.js.ep:110 themes/default/templates/partial/common.js.ep:90
msgid "Unable to copy to clipboard"
msgstr ""
#. ($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 ""
#: lib/Lutim/Controller/Image.pm:574 lib/Lutim/Controller/Image.pm:619 lib/Lutim/Controller/Image.pm:660 lib/Lutim/Controller/Image.pm:703 lib/Lutim/Controller/Image.pm:715 lib/Lutim/Controller/Image.pm:726 lib/Lutim/Controller/Image.pm:753 lib/Lutim/Plugin/Helpers.pm:88
msgid "Unable to find the image: it has been deleted."
msgstr ""
#: lib/Lutim/Controller/Image.pm:145
msgid "Unable to get counter"
msgstr ""
#: themes/default/templates/about.html.ep:17
msgid "Unlike many image sharing services, you don't give us rights on uploaded images."
msgstr ""
#: themes/default/templates/index.html.ep:180 themes/default/templates/index.html.ep:219
msgid "Upload an image with its URL"
msgstr ""
#: themes/default/templates/myfiles.html.ep:125
msgid "Uploaded at"
msgstr ""
#: themes/default/templates/stats.html.ep:6
msgid "Uploaded files by days"
msgstr ""
#. ($c->app->config('contact')
#: lib/Lutim/Plugin/Helpers.pm:221
msgid "Uploading is currently disabled, please try later or contact the administrator (%1)."
msgstr ""
#: themes/default/templates/index.html.ep:83 themes/default/templates/index.html.ep:85 themes/default/templates/myfiles.html.ep:122 themes/default/templates/partial/lutim.js.ep:72 themes/default/templates/partial/lutim.js.ep:76
msgid "View link"
msgstr ""
#: themes/default/templates/about.html.ep:22
msgid "What about the software which provides the service?"
msgstr ""
#: themes/default/templates/about.html.ep:3
msgid "What is Lutim?"
msgstr ""
#: themes/default/templates/about.html.ep:15
msgid "Who owns rights on images uploaded on Lutim?"
msgstr ""
#: 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 ""
#: 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 ""
#: themes/default/templates/zip.html.ep:6
msgid "You asked to download a zip archive for too much files."
msgstr ""
#: 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 ""
#: lib/Lutim/Controller/Authent.pm:27
msgid "You have been successfully logged in."
msgstr ""
#: lib/Lutim/Controller/Authent.pm:66 themes/default/templates/logout.html.ep:3
msgid "You have been successfully logged out."
msgstr ""
#: themes/default/templates/gallery.html.ep:31
msgid "Zoom in/out"
msgstr ""
#: themes/default/templates/about.html.ep:27
msgid "and on"
msgstr ""
#: themes/default/templates/about.html.ep:40
msgid "arabic translation"
msgstr ""
#: themes/default/templates/about.html.ep:27
msgid "core developer"
msgstr ""
#: lib/Lutim.pm:348 lib/Lutim/Command/cron/stats.pm:157 lib/Lutim/Command/cron/stats.pm:171 lib/Lutim/Command/cron/stats.pm:188 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 ""
#: themes/default/templates/about.html.ep:38
msgid "occitan translation"
msgstr ""
#: themes/default/templates/about.html.ep:27
msgid "on"
msgstr ""
#: themes/default/templates/about.html.ep:39
msgid "paste image to upload ability"
msgstr ""
#: themes/default/templates/about.html.ep:41
msgid "russian translation"
msgstr ""
#: themes/default/templates/about.html.ep:36
msgid "spanish translation"
msgstr ""
#: themes/default/templates/about.html.ep:28
msgid "webapp developer"
msgstr ""

View File

@@ -0,0 +1,689 @@
# Lutim language file
# Copyright (C) 2014 Luc Didry
# This file is distributed under the same license as the Lutim package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
# Luc Didry <luc@framasoft.org>, 2018. #zanata
# Quentí, 2018. #zanata
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"PO-Revision-Date: 2018-07-29 08:17+0000\n"
"Last-Translator: Luc Didry <luc@framasoft.org>\n"
"Language-Team: Occitan (http://www.transifex.com/fiat-tux/lutim/language/oc/"
")\n"
"Language: oc\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Zanata 4.5.0\n"
#. (7)
#. (30)
#. ($delay)
#. (config('max_delay')
#: lib/Lutim/Command/cron/stats.pm:147 lib/Lutim/Command/cron/stats.pm:148 lib/Lutim/Command/cron/stats.pm:161 lib/Lutim/Command/cron/stats.pm:162 lib/Lutim/Command/cron/stats.pm:178 lib/Lutim/Command/cron/stats.pm:179 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 jorns"
#. ($total)
#: themes/default/templates/stats.html.ep:2
msgid "%1 sent images on this instance from beginning."
msgstr "%1 imatges mandats sus aquesta instància dempuèi lo començament."
#: themes/default/templates/index.html.ep:208
msgid "-or-"
msgstr "-o-"
#: lib/Lutim.pm:350 lib/Lutim/Command/cron/stats.pm:149 lib/Lutim/Command/cron/stats.pm:163 lib/Lutim/Command/cron/stats.pm:180 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 an"
#: lib/Lutim.pm:349 lib/Lutim/Command/cron/stats.pm:146 lib/Lutim/Command/cron/stats.pm:160 lib/Lutim/Command/cron/stats.pm:177 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 oras"
#: themes/default/templates/partial/myfiles.js.ep:180
msgid ": Error while trying to get the counter."
msgstr " : Error al moment de recuperar lo comptador."
#: themes/default/templates/partial/navbar.html.ep:77
msgid "About"
msgstr "A prepaus"
#: lib/Lutim/Command/cron/stats.pm:142 themes/default/templates/raw.html.ep:3
msgid "Active images"
msgstr "Imatges actius"
#: lib/Lutim/Controller/Image.pm:327
msgid "An error occured while downloading the image."
msgstr "Una error es apareguda pendent lo telecargament de l'imatge."
#: themes/default/templates/zip.html.ep:2
msgid "Archives download"
msgstr "Telecargar los archius"
#: 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"
msgstr "Tornar a la pagina d'acuèlh"
#: themes/default/templates/index.html.ep:211 themes/default/templates/index.html.ep:212
msgid "Click to open the file browser"
msgstr "Clicatz per utilizar lo navigator de fichièr"
#: themes/default/templates/myfiles.html.ep:51
msgid "Close"
msgstr "Tampar"
#: themes/default/templates/gallery.html.ep:29
msgid "Close (Esc)"
msgstr "Tampar (Esc)"
#: themes/default/templates/about.html.ep:30
msgid "Contributors"
msgstr "Contributors"
#: themes/default/templates/partial/common.js.ep:113 themes/default/templates/partial/common.js.ep:93
msgid "Copied to clipboard"
msgstr "Copiat al quichapapièrs"
#: 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 "Copiar totes los ligams de visualizacion dins lo quichapapièrs"
#: themes/default/templates/index.html.ep:103 themes/default/templates/index.html.ep:111 themes/default/templates/index.html.ep:18 themes/default/templates/index.html.ep:36 themes/default/templates/index.html.ep:54 themes/default/templates/index.html.ep:87 themes/default/templates/index.html.ep:95 themes/default/templates/myfiles.html.ep:104 themes/default/templates/myfiles.html.ep:68 themes/default/templates/myfiles.html.ep:86 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:142
msgid "Copy to clipboard"
msgstr "Copiar dins lo quichapapièrs"
#: themes/default/templates/myfiles.html.ep:123
msgid "Counter"
msgstr "Comptador"
#: themes/default/templates/stats.html.ep:18
msgid "Delay repartition chart for disabled images"
msgstr "Grafic de despartiment dels delais pels imatges desactivats"
#: themes/default/templates/stats.html.ep:15
msgid "Delay repartition chart for enabled images"
msgstr "Grafic de despartiment dels delais pels imatges activats"
#: 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?"
msgstr "Suprimir al primièr accès ?"
#: lib/Lutim/Command/cron/stats.pm:143 themes/default/templates/raw.html.ep:4
msgid "Deleted images"
msgstr "Imatges suprimits"
#: lib/Lutim/Command/cron/stats.pm:144 themes/default/templates/raw.html.ep:5
msgid "Deleted images in 30 days"
msgstr "Imatges per èsser suprimits dins 30 jorns"
#: themes/default/templates/index.html.ep:116 themes/default/templates/myfiles.html.ep:127 themes/default/templates/partial/common.js.ep:178 themes/default/templates/partial/common.js.ep:181
msgid "Deletion link"
msgstr "Ligam de supression"
#: themes/default/templates/gallery.html.ep:10
msgid "Download all images"
msgstr "Telecargar totes los imatges"
#: themes/default/templates/index.html.ep:101 themes/default/templates/index.html.ep:99 themes/default/templates/partial/lutim.js.ep:102 themes/default/templates/partial/lutim.js.ep:98
msgid "Download link"
msgstr "Ligam de telecargament"
#: themes/default/templates/index.html.ep:28 themes/default/templates/index.html.ep:31 themes/default/templates/myfiles.html.ep:78 themes/default/templates/myfiles.html.ep:81
msgid "Download zip link"
msgstr "Ligam de telecargament de l'archiu dels imatges"
#: themes/default/templates/index.html.ep:207
msgid "Drag & drop images here"
msgstr "Lisatz e depausatz vòstres imatges aquí"
#: 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 ""
"Depausatz vòstres imatges dins la zòna prevista per aquò o seleccionatz un "
"fichièr d'un biais classic e Lutim vos donarà quatre URLs en torna. Una per "
"afichar l'imatge, una mai per lo telecargar dirèctament, una per l'utilizar "
"suls malhums socials e una darrièra per suprimir vòstre imatge quand "
"volguèssetz."
#: themes/default/templates/index.html.ep:168 themes/default/templates/index.html.ep:199
msgid "Encrypt the image (Lutim does not keep the key)."
msgstr "Chifrar l'imatge (Lutim garda pas la clau)."
#: 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 "Una error es apareguda al moment de modificar l'imatge."
#: themes/default/templates/stats.html.ep:10
msgid "Evolution of total files"
msgstr "Evolucion del nombre total de fichièrs"
#: themes/default/templates/myfiles.html.ep:126
msgid "Expires at"
msgstr "S'acaba lo"
#: themes/default/templates/myfiles.html.ep:112
msgid "Export localStorage data"
msgstr "Exportar las donadas localStorage"
#: themes/default/templates/myfiles.html.ep:121
msgid "File name"
msgstr "Nom del fichièr"
#: themes/default/templates/about.html.ep:24
msgid ""
"For more details, see the <a href=\"https://framagit.org/luc/"
"lutim\">homepage of the project</a>."
msgstr ""
"Per mai de detalhs, consultatz la <a href=\"https://framagit.org/luc/"
"lutim\">pagina</a> del projècte."
#: themes/default/templates/partial/navbar.html.ep:80
msgid "Fork me!"
msgstr "Tustatz-me !"
#: 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"
msgstr "Ligam cap a la galariá"
#: 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 "Fasètz Ctrl+C puèi picatz Entrada per copiar lo ligam"
#: themes/default/templates/layouts/default.html.ep:47
msgid "Homepage"
msgstr "Acuèlh"
#: themes/default/templates/about.html.ep:20
msgid "How do you pronounce Lutim?"
msgstr "Cossí cal prononciar Lutim ?"
#: themes/default/templates/about.html.ep:6
msgid "How does it work?"
msgstr "Cossí aquò fonciona ?"
#: themes/default/templates/about.html.ep:18
msgid "How to report an image?"
msgstr "Qué far per senhalar un imatge ?"
#: 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 ""
"Se los fichièrs son ben estats suprimits se o avètz demandat, lors "
"signaturas SHA512 son gardadas."
#: themes/default/templates/index.html.ep:181 themes/default/templates/index.html.ep:221
msgid "Image URL"
msgstr "URL de l'imatge"
#: lib/Lutim/Command/cron/stats.pm:141 themes/default/templates/raw.html.ep:2
msgid "Image delay"
msgstr "Delai de l'imatge"
#: themes/default/templates/partial/common.js.ep:157
msgid "Image deleted"
msgstr "Imatge suprimit"
#: lib/Lutim/Controller/Image.pm:753
msgid "Image not found."
msgstr "Imatge pas trobat."
#: themes/default/templates/myfiles.html.ep:113
msgid "Import localStorage data"
msgstr "Importar las donadas localStorage"
#: themes/default/templates/partial/navbar.html.ep:69
msgid "Informations"
msgstr "Informacions"
#: themes/default/templates/partial/navbar.html.ep:25
msgid "Install webapp"
msgstr "Installar la webapp"
#: themes/default/templates/partial/navbar.html.ep:21
msgid "Instance's statistics"
msgstr "Estatisticas de l'instància"
#: themes/default/templates/about.html.ep:11
msgid "Is it really anonymous?"
msgstr "Es vertadièrament anonim ?"
#: themes/default/templates/about.html.ep:9
msgid "Is it really free (as in free beer)?"
msgstr "Es vertadièrament gratuit ?"
#: 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 ""
"Òm pronóncia coma en occitan lengadocian, LU-TI-N, amb una M finala que sona "
"N, o coma la paraula francesa <a href=\"https://fr.wikipedia.org/wiki/"
"Lutin\">lutin</a> (/ly.tɛ̃/)."
#: themes/default/templates/index.html.ep:171 themes/default/templates/index.html.ep:202
msgid "Keep EXIF tags"
msgstr "Conservar las donadas EXIF"
#: themes/default/templates/partial/navbar.html.ep:43
msgid "Language"
msgstr "Lenga"
#: themes/default/templates/index.html.ep:136 themes/default/templates/index.html.ep:184 themes/default/templates/index.html.ep:224 themes/default/templates/partial/lutim.js.ep:165
msgid "Let's go!"
msgstr "Zo !"
#: themes/default/templates/partial/navbar.html.ep:74
msgid "License:"
msgstr "Licéncia :"
#: themes/default/templates/index.html.ep:107 themes/default/templates/index.html.ep:109 themes/default/templates/partial/lutim.js.ep:112 themes/default/templates/partial/lutim.js.ep:116
msgid "Link for share on social networks"
msgstr "Ligam per partejar suls malhums socials"
#: themes/default/templates/login.html.ep:8
msgid "Login"
msgstr "Connexion"
#: themes/default/templates/partial/navbar.html.ep:33
msgid "Logout"
msgstr "Desconnexion"
#: 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 pòt pas comprimir tan d'imatge d'un còp, a doncas trocejat vòstra "
"demanda en multiplas URLs"
#: 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 es un servici gratuit e anonim dalbergament dimatges. Sagís tanben "
"del nom del logicial (liure) que fornís aqueste servici."
#: themes/default/templates/about.html.ep:25
msgid "Main developers"
msgstr "Desvolopaires de l'aplicacion"
#: themes/default/templates/index.html.ep:91 themes/default/templates/index.html.ep:93 themes/default/templates/partial/lutim.js.ep:86 themes/default/templates/partial/lutim.js.ep:89
msgid "Markdown syntax"
msgstr "Sintaxi Markdown"
#: themes/default/templates/partial/myfiles.js.ep:149
msgid "Modify expiration delay"
msgstr "Modificar lo delai d'expiracion"
#: themes/default/templates/myfiles.html.ep:7 themes/default/templates/partial/navbar.html.ep:18
msgid "My images"
msgstr "Mos imatges"
#: themes/default/templates/gallery.html.ep:45
msgid "Next (arrow right)"
msgstr "Seguent (sageta dreita)"
#: themes/default/templates/partial/myfiles.js.ep:105 themes/default/templates/partial/myfiles.js.ep:132
msgid "No limit"
msgstr "Pas cap de data d'expiracion"
#: themes/default/templates/index.html.ep:183 themes/default/templates/index.html.ep:216
msgid "Only images are allowed"
msgstr "Solament son acceptats los imatges"
#: 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 ""
"Solament los imatges mandats amb aqueste navigador seràn listats aquí. Las "
"menudalhas son gardadas en localStorage : se escafatz vòstras donadas "
"localStorage, perdretz aquelas menudalhas."
#: 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 ""
"Solament lo qu'a mandat ! (ben, solament se ten los dreits exclusius dels "
"imatges abans de los mandar)"
#: themes/default/templates/login.html.ep:12
msgid "Password"
msgstr "Senhal"
#: themes/default/templates/zip.html.ep:12
msgid "Please click on each URL to download the different zip files."
msgstr ""
"Mercés de clicar sus cada URL per telecargar los diferents archius ZIP."
#. (config('contact')
#: themes/default/templates/about.html.ep:19
msgid "Please contact the administrator: %1"
msgstr "Mercés de contactar l'administrator : %1"
#: lib/Lutim/Controller/Authent.pm:36
msgid "Please, check your credentials: unable to authenticate."
msgstr ""
"Mercés de verificar vòstres identificants:impossible de vos autentificar."
#: themes/default/templates/gallery.html.ep:43
msgid "Previous (arrow left)"
msgstr "Precedent (sageta esquèrra)"
#: 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"
msgstr "Ligam cap a un imatge aleatòri"
#: themes/default/templates/stats.html.ep:22
msgid "Raw stats"
msgstr "Estatisticas brutas"
#: themes/default/templates/myfiles.html.ep:52
msgid "Save changes"
msgstr "Enregistrar las causidas"
#: themes/default/templates/index.html.ep:176
msgid "Send an image"
msgstr "Mandar un imatge"
#: 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 "Connexion"
#: 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"
msgstr "Un problèma es aparegut"
#. ($c->config('contact')
#: lib/Lutim/Controller/Image.pm:760
msgid ""
"Something went wrong when creating the zip file. Try again later or contact "
"the administrator (%1)."
msgstr ""
"Quicòm a trucat pendent la creacion de l'archiu. Mercés de tornar ensajar "
"pus tard o de contactar l'administrator (%1)."
#: themes/default/templates/partial/navbar.html.ep:55
msgid "Support the author"
msgstr "Sostenir lautor"
#: themes/default/templates/partial/navbar.html.ep:63
msgid "Support the author on Liberapay"
msgstr "Sostenir l'autor sus Liberapay"
#: themes/default/templates/partial/navbar.html.ep:60
msgid "Support the author on Tipeee"
msgstr "Sostenir l'autor sus Tipeee"
#: 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 ""
"LIP de la persona que mandèt l'imatge es gardada pendent un delai que "
"depend de l'administrator de l'instància (per l'instància oficiala que lo "
"servidor es en França, es un delai d'un an)."
#: 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 ""
"Lo logicial Lutim es un <a href=\"https://oc.wikipedia.org/wiki/"
"Logicial_liure\">logicial liure</a>, que permet de lo telecargar e de "
"linstallar sus vòstre pròpri servidor. Gaitatz l<a href=\"https://www.gnu."
"org/licenses/agpl-3.0.html\">AGPL</a> per veire que son vòstres dreits"
#: lib/Lutim/Controller/Image.pm:346
msgid "The URL is not valid."
msgstr "L'URL n'es pas valida."
#: 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 ""
"Lo processús automatic de telecargament obrirà un onglet dins lo navigato "
"per cada ligam. Vos cal autorizar las popups per Lutim."
#: themes/default/templates/partial/myfiles.js.ep:32
msgid "The data has been successfully imported."
msgstr "Las donadas son ben estadas importadas."
#: lib/Lutim/Controller/Image.pm:159 lib/Lutim/Controller/Image.pm:227
msgid "The delete token is invalid."
msgstr "Lo geton de supression es invalid."
#. ($upload->filename)
#: lib/Lutim/Controller/Image.pm:487
msgid "The file %1 is not an image."
msgstr "Lo fichièr %1 es pas un imatge."
#. ($tx->res->max_message_size)
#. ($c->req->max_message_size)
#. (config('max_file_size')
#: lib/Lutim/Controller/Image.pm:310 lib/Lutim/Controller/Image.pm:379 themes/default/templates/partial/lutim.js.ep:249
msgid "The file exceed the size limit (%1)"
msgstr "Lo fichièr depassa lo limit de talha (%1)"
#: themes/default/templates/stats.html.ep:12
msgid "The graph's datas are not updated in real-time."
msgstr "Las donadas del grafic son pas mesas a jorn en temps real."
#. ($image->filename)
#: lib/Lutim/Controller/Image.pm:229
msgid "The image %1 has already been deleted."
msgstr "L'imatge %1 es ja estat suprimit."
#. ($image->filename)
#: lib/Lutim/Controller/Image.pm:238 lib/Lutim/Controller/Image.pm:243
msgid "The image %1 has been successfully deleted"
msgstr "L'imatge %1 es estat suprimit amb succès."
#: lib/Lutim/Controller/Image.pm:167
msgid "The image's delay has been successfully modified"
msgstr "Lo delai de l'imatge es plan estat modificat."
#: themes/default/templates/index.html.ep:63
msgid "The images are encrypted on the server (Lutim does not keep the key)."
msgstr "Los imatges son chifrats sul servidor (Lutim garda pas la clau)."
#: 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 ""
"Los imatges depausats sus Lutim pòdon èsser gardats sens fin, o sescafar "
"tre lo primièr afichatge o al cap d'un delai causit entre los prepausats."
#: themes/default/templates/partial/gallery.js.ep:257
msgid "There is XXXX image(s) in the gallery"
msgstr "I a XXXX imatge(s) dins la galariá"
#. ($c->config->{contact})
#: lib/Lutim/Controller/Image.pm:484
msgid "There is no more available URL. Retry or contact the administrator. %1"
msgstr ""
"I a pas mai d'URL disponiblas. Mercés de tornar ensajar o de contactar "
"l'administrator. %1."
#: themes/default/templates/gallery.html.ep:30
msgid "Toggle fullscreen"
msgstr "Passar al plen ecran"
#: themes/default/templates/partial/navbar.html.ep:8
msgid "Toggle navigation"
msgstr "Passar en navigacion"
#: lib/Lutim/Command/cron/stats.pm:150 themes/default/templates/raw.html.ep:11
msgid "Total"
msgstr "Total"
#: themes/default/templates/index.html.ep:78 themes/default/templates/partial/lutim.js.ep:17
msgid "Tweet it!"
msgstr "Tweetejatz-lo !"
#: themes/default/templates/partial/common.js.ep:110 themes/default/templates/partial/common.js.ep:90
msgid "Unable to copy to clipboard"
msgstr "Fracàs de la còpia al quichapapièrs"
#. ($short)
#: lib/Lutim/Controller/Image.pm:107 lib/Lutim/Controller/Image.pm:201 lib/Lutim/Controller/Image.pm:272
msgid "Unable to find the image %1."
msgstr "Impossible de trobar l'imatge %1."
#: lib/Lutim/Controller/Image.pm:573 lib/Lutim/Controller/Image.pm:618 lib/Lutim/Controller/Image.pm:657 lib/Lutim/Controller/Image.pm:700 lib/Lutim/Controller/Image.pm:712 lib/Lutim/Controller/Image.pm:723 lib/Lutim/Controller/Image.pm:750 lib/Lutim/Plugin/Helpers.pm:88
msgid "Unable to find the image: it has been deleted."
msgstr "Impossible de trobar l'imatge : es estat suprimit."
#: lib/Lutim/Controller/Image.pm:144
msgid "Unable to get counter"
msgstr "Impossible de recuperar lo comptador"
#: themes/default/templates/about.html.ep:17
msgid ""
"Unlike many image sharing services, you don't give us rights on uploaded "
"images."
msgstr ""
"A l'invèrse de la màger part dels servicis de partiment d'imatge, daissatz "
"pas cap de dreit suls imatges que mandatz."
#: themes/default/templates/index.html.ep:180 themes/default/templates/index.html.ep:219
msgid "Upload an image with its URL"
msgstr "Depausar un imatge per son URL"
#: themes/default/templates/myfiles.html.ep:125
msgid "Uploaded at"
msgstr "Mandat lo"
#: themes/default/templates/stats.html.ep:6
msgid "Uploaded files by days"
msgstr "Fichièrs mandats per jorn"
#. ($c->app->config('contact')
#: lib/Lutim/Plugin/Helpers.pm:221
msgid ""
"Uploading is currently disabled, please try later or contact the "
"administrator (%1)."
msgstr ""
"La mesa en linha es desactivada pel moment, mercés de tornar ensajar mai "
"tard o de contactar l'administrator (%1)."
#: themes/default/templates/index.html.ep:83 themes/default/templates/index.html.ep:85 themes/default/templates/myfiles.html.ep:122 themes/default/templates/partial/lutim.js.ep:72 themes/default/templates/partial/lutim.js.ep:76
msgid "View link"
msgstr "Ligam d'afichatge"
#: themes/default/templates/about.html.ep:22
msgid "What about the software which provides the service?"
msgstr "E a prepaus del logicial que fornís lo servici ?"
#: themes/default/templates/about.html.ep:3
msgid "What is Lutim?"
msgstr "Ques aquò Lutim ?"
#: themes/default/templates/about.html.ep:15
msgid "Who owns rights on images uploaded on Lutim?"
msgstr "Qual a los dreits suls imatges mandats sus Lutim ?"
#: 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 ""
"Òc, es aquò ! Al contrari, per de rasons legalas, vòstra adreça IP serà "
"enregistrada quand mandaretz un imatge. Perdetz pas lo cap, normalament es "
"çò normal pels demai dels sites suls quals mandatz de fichièrs !"
#: 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 ""
"Òc, o es ! Al contrari, s'avètz enveja de sosténer lo desvolopaire, podètz "
"far un microdon amb <a href=\"https://www.tipeee.com/fiat-tux\">Tipeee</a> o "
"via <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 ""
"Avètz demandat de telecargar tròp d'imatges d'un còp dins un archiu ZIP."
#: 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 ""
"Podètz, d'un biais facultatiu, demandar que l'imatge o los imatges depausats "
"sus Lutim sián suprimits aprèp lor primièr afichatge (o telecargament) o al "
"cap d'un delai causit entre las prepausadas."
#: lib/Lutim/Controller/Authent.pm:27
msgid "You have been successfully logged in."
msgstr "Sètz ben estat·ada connectat·ada."
#: lib/Lutim/Controller/Authent.pm:66 themes/default/templates/logout.html.ep:3
msgid "You have been successfully logged out."
msgstr "Sètz ben estat desconnectat."
#: themes/default/templates/gallery.html.ep:31
msgid "Zoom in/out"
msgstr "Agrandir/Reduire"
#: themes/default/templates/about.html.ep:27
msgid "and on"
msgstr "e sus"
#: themes/default/templates/about.html.ep:40
msgid "arabic translation"
msgstr "traduccion en arabi"
#: themes/default/templates/about.html.ep:27
msgid "core developer"
msgstr "desvolopaire màger"
#: lib/Lutim.pm:348 lib/Lutim/Command/cron/stats.pm:145 lib/Lutim/Command/cron/stats.pm:159 lib/Lutim/Command/cron/stats.pm:176 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 "Pas cap de limitacion de durada"
#: themes/default/templates/about.html.ep:38
msgid "occitan translation"
msgstr "traduccion en occitan"
#: themes/default/templates/about.html.ep:27
msgid "on"
msgstr "sus"
#: themes/default/templates/about.html.ep:39
msgid "paste image to upload ability"
msgstr "possibilitat de pegar un imatge per lo mandar"
#: themes/default/templates/about.html.ep:41
msgid "russian translation"
msgstr "traduccion en rus"
#: themes/default/templates/about.html.ep:36
msgid "spanish translation"
msgstr "traduccion en espanhòl"
#: themes/default/templates/about.html.ep:28
msgid "webapp developer"
msgstr "desvolopaire de la webapp"

View File

@@ -0,0 +1,682 @@
# Luc Didry <luc@framasoft.org>, 2018. #zanata
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"PO-Revision-Date: 2018-07-29 08:17+0000\n"
"Last-Translator: Copied by Zanata <copied-by-zanata@zanata.org>\n"
"Language-Team: Russian\n"
"Language: ru\n"
"X-Generator: Zanata 4.5.0\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"
#. (7)
#. (30)
#. ($delay)
#. (config('max_delay')
#: lib/Lutim/Command/cron/stats.pm:147 lib/Lutim/Command/cron/stats.pm:148 lib/Lutim/Command/cron/stats.pm:161 lib/Lutim/Command/cron/stats.pm:162 lib/Lutim/Command/cron/stats.pm:178 lib/Lutim/Command/cron/stats.pm:179 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 дней"
#. ($total)
#: themes/default/templates/stats.html.ep:2
msgid "%1 sent images on this instance from beginning."
msgstr "%1 изображений загружено в этот экземпляр с самого начала."
#: themes/default/templates/index.html.ep:208
msgid "-or-"
msgstr "-или-"
#: lib/Lutim.pm:350 lib/Lutim/Command/cron/stats.pm:149 lib/Lutim/Command/cron/stats.pm:163 lib/Lutim/Command/cron/stats.pm:180 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 год"
#: lib/Lutim.pm:349 lib/Lutim/Command/cron/stats.pm:146 lib/Lutim/Command/cron/stats.pm:160 lib/Lutim/Command/cron/stats.pm:177 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 часа"
#: themes/default/templates/partial/myfiles.js.ep:180
msgid ": Error while trying to get the counter."
msgstr ": Error while trying to get the counter."
#: themes/default/templates/partial/navbar.html.ep:77
msgid "About"
msgstr "О Lutim"
#: lib/Lutim/Command/cron/stats.pm:142 themes/default/templates/raw.html.ep:3
msgid "Active images"
msgstr "Активные изображения"
#: lib/Lutim/Controller/Image.pm:327
msgid "An error occured while downloading the image."
msgstr "Произошла ошибка при скачивании изображения."
#: themes/default/templates/zip.html.ep:2
msgid "Archives download"
msgstr "Archives download"
#: 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"
msgstr "Вернуться на главную страницу"
#: themes/default/templates/index.html.ep:211 themes/default/templates/index.html.ep:212
msgid "Click to open the file browser"
msgstr "Щёлкните для выбора файлов"
#: themes/default/templates/myfiles.html.ep:51
msgid "Close"
msgstr "Закрыть"
#: themes/default/templates/gallery.html.ep:29
msgid "Close (Esc)"
msgstr "Закрыть (Esc)"
#: themes/default/templates/about.html.ep:30
msgid "Contributors"
msgstr "Участники"
#: themes/default/templates/partial/common.js.ep:113 themes/default/templates/partial/common.js.ep:93
msgid "Copied to clipboard"
msgstr ""
#: 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 "Скопировать в буфер все ссылки на просмотр"
#: themes/default/templates/index.html.ep:103 themes/default/templates/index.html.ep:111 themes/default/templates/index.html.ep:18 themes/default/templates/index.html.ep:36 themes/default/templates/index.html.ep:54 themes/default/templates/index.html.ep:87 themes/default/templates/index.html.ep:95 themes/default/templates/myfiles.html.ep:104 themes/default/templates/myfiles.html.ep:68 themes/default/templates/myfiles.html.ep:86 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:142
msgid "Copy to clipboard"
msgstr "Скопировать в буфер"
#: themes/default/templates/myfiles.html.ep:123
msgid "Counter"
msgstr "Счётчик"
#: themes/default/templates/stats.html.ep:18
msgid "Delay repartition chart for disabled images"
msgstr "Распределение сроков хранения недоступных изображений"
#: themes/default/templates/stats.html.ep:15
msgid "Delay repartition chart for enabled images"
msgstr "Распределение сроков хранения доступных изображений"
#: 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?"
msgstr "Удалить после первого просмотра?"
#: lib/Lutim/Command/cron/stats.pm:143 themes/default/templates/raw.html.ep:4
msgid "Deleted images"
msgstr "Удалённые изображения"
#: lib/Lutim/Command/cron/stats.pm:144 themes/default/templates/raw.html.ep:5
msgid "Deleted images in 30 days"
msgstr "Удалить изображения через 30 дней"
#: themes/default/templates/index.html.ep:116 themes/default/templates/myfiles.html.ep:127 themes/default/templates/partial/common.js.ep:178 themes/default/templates/partial/common.js.ep:181
msgid "Deletion link"
msgstr "Ссылка на удаление"
#: themes/default/templates/gallery.html.ep:10
msgid "Download all images"
msgstr "Скачать все изображения"
#: themes/default/templates/index.html.ep:101 themes/default/templates/index.html.ep:99 themes/default/templates/partial/lutim.js.ep:102 themes/default/templates/partial/lutim.js.ep:98
msgid "Download link"
msgstr "Ссылка на скачивание"
#: themes/default/templates/index.html.ep:28 themes/default/templates/index.html.ep:31 themes/default/templates/myfiles.html.ep:78 themes/default/templates/myfiles.html.ep:81
msgid "Download zip link"
msgstr "Ссылка на скачивание zip-архивом"
#: themes/default/templates/index.html.ep:207
msgid "Drag & drop images here"
msgstr "Перетащите и бросьте изображения сюда"
#: 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 ""
"Перетащите и бросьте изображение либо воспользуйтесь традиционным путём для "
"загрузки файлов, и Lutim предоставит вам четыре URL. Один для просмотра "
"изображения, другой — для скачивания, следующий вы можете использовать в "
"социальных сетях и последний — для удаления изображения, когда заходите."
#: themes/default/templates/index.html.ep:168 themes/default/templates/index.html.ep:199
msgid "Encrypt the image (Lutim does not keep the key)."
msgstr "Зашифровать изображение (Lutim не хранит ключ)."
#: 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 "Ошибка при попытке модифицировать изображение."
#: themes/default/templates/stats.html.ep:10
msgid "Evolution of total files"
msgstr "Общее количество файлов"
#: themes/default/templates/myfiles.html.ep:126
msgid "Expires at"
msgstr "Истекает в"
#: themes/default/templates/myfiles.html.ep:112
msgid "Export localStorage data"
msgstr ""
#: themes/default/templates/myfiles.html.ep:121
msgid "File name"
msgstr "Имя файла"
#: themes/default/templates/about.html.ep:24
msgid ""
"For more details, see the <a href=\"https://framagit.org/luc/"
"lutim\">homepage of the project</a>."
msgstr ""
"Чтоб узнать больше, посетите <a href=\"https://framagit.org/luc/"
"lutim\">главную страницу проекта</a>."
#: themes/default/templates/partial/navbar.html.ep:80
msgid "Fork me!"
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"
msgstr "Ссылка на галерею"
#: 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 "Нажмите Ctrl+C, а затем Enter для копирования короткой ссылки"
#: themes/default/templates/layouts/default.html.ep:47
msgid "Homepage"
msgstr "Главная страница"
#: themes/default/templates/about.html.ep:20
msgid "How do you pronounce Lutim?"
msgstr "Как произносится Lutim?"
#: themes/default/templates/about.html.ep:6
msgid "How does it work?"
msgstr "Как это работает?"
#: themes/default/templates/about.html.ep:18
msgid "How to report an image?"
msgstr "Как пожаловаться на изображение?"
#: 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 ""
"Если файлы были удалены, потому что вы указали это при их загрузке, их "
"контрольные суммы SHA512 сохранятся."
#: themes/default/templates/index.html.ep:181 themes/default/templates/index.html.ep:221
msgid "Image URL"
msgstr "URL изображения"
#: lib/Lutim/Command/cron/stats.pm:141 themes/default/templates/raw.html.ep:2
msgid "Image delay"
msgstr "Срок хранения"
#: themes/default/templates/partial/common.js.ep:157
msgid "Image deleted"
msgstr ""
#: lib/Lutim/Controller/Image.pm:753
msgid "Image not found."
msgstr "Изображение не найдено."
#: themes/default/templates/myfiles.html.ep:113
msgid "Import localStorage data"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:69
msgid "Informations"
msgstr "Информация"
#: themes/default/templates/partial/navbar.html.ep:25
msgid "Install webapp"
msgstr "Установить веб-приложение"
#: themes/default/templates/partial/navbar.html.ep:21
msgid "Instance's statistics"
msgstr "Статистика экземпляра"
#: themes/default/templates/about.html.ep:11
msgid "Is it really anonymous?"
msgstr "Это действительно анонимно?"
#: themes/default/templates/about.html.ep:9
msgid "Is it really free (as in free beer)?"
msgstr "Это действительно бесплатно (as in free beer)?"
#: 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 ""
"Как французское слово <a href=\"https://fr.wikipedia.org/wiki/Lutin\">lutin</"
"a> (/ly.tɛ̃/)."
#: themes/default/templates/index.html.ep:171 themes/default/templates/index.html.ep:202
msgid "Keep EXIF tags"
msgstr "Сохранить EXIF-теги"
#: themes/default/templates/partial/navbar.html.ep:43
msgid "Language"
msgstr "Язык"
#: themes/default/templates/index.html.ep:136 themes/default/templates/index.html.ep:184 themes/default/templates/index.html.ep:224 themes/default/templates/partial/lutim.js.ep:165
msgid "Let's go!"
msgstr "Вперёд!"
#: themes/default/templates/partial/navbar.html.ep:74
msgid "License:"
msgstr "Лицензия:"
#: themes/default/templates/index.html.ep:107 themes/default/templates/index.html.ep:109 themes/default/templates/partial/lutim.js.ep:112 themes/default/templates/partial/lutim.js.ep:116
msgid "Link for share on social networks"
msgstr "Ссылка для того, чтоб поделиться в социальных сетях"
#: themes/default/templates/login.html.ep:8
msgid "Login"
msgstr ""
#: themes/default/templates/partial/navbar.html.ep:33
msgid "Logout"
msgstr ""
#: 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 не может сархивировать так много картинок за раз, поэтому ваш запрос "
"разбит на несколько URL."
#: 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 — это бесплатный (as in free beer) и анонимный сервис размещения "
"изображений. Также это название свободного (as in free speech) программного "
"обеспечения, предоставляющего этот сервис."
#: themes/default/templates/about.html.ep:25
msgid "Main developers"
msgstr "Главные разработчики"
#: themes/default/templates/index.html.ep:91 themes/default/templates/index.html.ep:93 themes/default/templates/partial/lutim.js.ep:86 themes/default/templates/partial/lutim.js.ep:89
msgid "Markdown syntax"
msgstr "Синтаксис Маркдауна"
#: themes/default/templates/partial/myfiles.js.ep:149
msgid "Modify expiration delay"
msgstr ""
#: themes/default/templates/myfiles.html.ep:7 themes/default/templates/partial/navbar.html.ep:18
msgid "My images"
msgstr "Мои изображения"
#: themes/default/templates/gallery.html.ep:45
msgid "Next (arrow right)"
msgstr "Следующий (стрелка вправо)"
#: themes/default/templates/partial/myfiles.js.ep:105 themes/default/templates/partial/myfiles.js.ep:132
msgid "No limit"
msgstr "Без ограничений"
#: themes/default/templates/index.html.ep:183 themes/default/templates/index.html.ep:216
msgid "Only images are allowed"
msgstr "Разрешены только изображения"
#: 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 ""
"Здесь перечислены только изображения, загруженные через браузер. Статистика "
"хранится в localStorage: если вы удалите данные localStorage, вы потеряете "
"эту статистику."
#: 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 ""
"Только тот, кто загрузил! (ну хорошо, только если он — единственный "
"правообладатель изображений до загрузки)"
#: themes/default/templates/login.html.ep:12
msgid "Password"
msgstr ""
#: themes/default/templates/zip.html.ep:12
msgid "Please click on each URL to download the different zip files."
msgstr ""
"Пожалуйста, щёлкните по каждому URL для скачивания отдельными zip-архивами."
#. (config('contact')
#: themes/default/templates/about.html.ep:19
msgid "Please contact the administrator: %1"
msgstr "Пожалуйста, свяжитесь с администратором: %1"
#: lib/Lutim/Controller/Authent.pm:36
msgid "Please, check your credentials: unable to authenticate."
msgstr ""
#: themes/default/templates/gallery.html.ep:43
msgid "Previous (arrow left)"
msgstr "Предыдущий (стрелка влево)"
#: 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"
msgstr ""
#: themes/default/templates/stats.html.ep:22
msgid "Raw stats"
msgstr "Сырые статистические данные"
#: themes/default/templates/myfiles.html.ep:52
msgid "Save changes"
msgstr ""
#: themes/default/templates/index.html.ep:176
msgid "Send an image"
msgstr "Послать изображение"
#: 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 ""
#: 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"
msgstr "Произошло что-то плохое"
#. ($c->config('contact')
#: lib/Lutim/Controller/Image.pm:760
msgid ""
"Something went wrong when creating the zip file. Try again later or contact "
"the administrator (%1)."
msgstr ""
"Что-то пошло не так при создании zip-архива. Попробуйте позже или свяжитесь "
"с администратором (%1)."
#: themes/default/templates/partial/navbar.html.ep:55
msgid "Support the author"
msgstr "Поддержать автора"
#: themes/default/templates/partial/navbar.html.ep:63
msgid "Support the author on Liberapay"
msgstr "Поддержать автора на Liberapay"
#: themes/default/templates/partial/navbar.html.ep:60
msgid "Support the author on Tipeee"
msgstr "Поддержать автора на Tipeee"
#: 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-адрес отправителя изображений сохраняется на время, зависящее от решения "
"администратора (официальное требование во Франции — один год)."
#: 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 ""
"Lutim — это <a href=\"https://ru.wikipedia.org/wiki/"
"%D0%A1%D0%B2%D0%BE%D0%B1%D0%BE%D0%B4%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%BD%D0%BE%D0%B5_%D0%BE%D0%B1%D0%B5%D1%81%D0%BF%D0%B5%D1%87%D0%B5%D0%BD%D0%B8%D0%B5\">свободное "
"программное обеспечение</a>, которое вы можете скачать и установить на свой "
"сервер. Посмотрите <a href=\"https://www.gnu.org/licenses/agpl-3.0."
"html\">AGPL</a>, чтоб увидеть, что вы можете делать."
#: lib/Lutim/Controller/Image.pm:346
msgid "The URL is not valid."
msgstr "Недопустимый URL."
#: 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 ""
"Процесс автоматического скачивания откроет вкладку в вашем браузере для "
"каждой ссылки. Вам надо разрешить всплывающие окна для Lutim."
#: themes/default/templates/partial/myfiles.js.ep:32
msgid "The data has been successfully imported."
msgstr ""
#: lib/Lutim/Controller/Image.pm:159 lib/Lutim/Controller/Image.pm:227
msgid "The delete token is invalid."
msgstr "Неправильный ключ для удаления."
#. ($upload->filename)
#: lib/Lutim/Controller/Image.pm:487
msgid "The file %1 is not an image."
msgstr "Файл %1 — не изображение."
#. ($tx->res->max_message_size)
#. ($c->req->max_message_size)
#. (config('max_file_size')
#: lib/Lutim/Controller/Image.pm:310 lib/Lutim/Controller/Image.pm:379 themes/default/templates/partial/lutim.js.ep:249
msgid "The file exceed the size limit (%1)"
msgstr "Размер файла превосходит ограничение (%1)"
#: themes/default/templates/stats.html.ep:12
msgid "The graph's datas are not updated in real-time."
msgstr "Данные графиков не обновляются в реальном времени."
#. ($image->filename)
#: lib/Lutim/Controller/Image.pm:229
msgid "The image %1 has already been deleted."
msgstr "Изображение %1 уже было удалено."
#. ($image->filename)
#: lib/Lutim/Controller/Image.pm:238 lib/Lutim/Controller/Image.pm:243
msgid "The image %1 has been successfully deleted"
msgstr "Изображение %1 успешно удалено"
#: lib/Lutim/Controller/Image.pm:167
msgid "The image's delay has been successfully modified"
msgstr "Срок хранения изображения успешно изменён"
#: themes/default/templates/index.html.ep:63
msgid "The images are encrypted on the server (Lutim does not keep the key)."
msgstr "Изображения зашифрованы на сервере (Lutim не хранит ключ)."
#: 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 ""
"Изображения, загружаемые в Lutim, могут храниться неопределённо долго либо "
"быть удалёнными после первого просмотра или по истечении определённого "
"промежутка времени."
#: themes/default/templates/partial/gallery.js.ep:257
msgid "There is XXXX image(s) in the gallery"
msgstr ""
#. ($c->config->{contact})
#: lib/Lutim/Controller/Image.pm:484
msgid "There is no more available URL. Retry or contact the administrator. %1"
msgstr ""
"Больше нет доступных URL. Попробуйте снова или свяжитесь с администратором. "
"%1"
#: themes/default/templates/gallery.html.ep:30
msgid "Toggle fullscreen"
msgstr "Переключить полноэкранный режим"
#: themes/default/templates/partial/navbar.html.ep:8
msgid "Toggle navigation"
msgstr "Переключить навигацию"
#: lib/Lutim/Command/cron/stats.pm:150 themes/default/templates/raw.html.ep:11
msgid "Total"
msgstr "Итого"
#: themes/default/templates/index.html.ep:78 themes/default/templates/partial/lutim.js.ep:17
msgid "Tweet it!"
msgstr "Твитнуть!"
#: themes/default/templates/partial/common.js.ep:110 themes/default/templates/partial/common.js.ep:90
msgid "Unable to copy to clipboard"
msgstr ""
#. ($short)
#: lib/Lutim/Controller/Image.pm:107 lib/Lutim/Controller/Image.pm:201 lib/Lutim/Controller/Image.pm:272
msgid "Unable to find the image %1."
msgstr "Невозможно найти изображение %1."
#: lib/Lutim/Controller/Image.pm:573 lib/Lutim/Controller/Image.pm:618 lib/Lutim/Controller/Image.pm:657 lib/Lutim/Controller/Image.pm:700 lib/Lutim/Controller/Image.pm:712 lib/Lutim/Controller/Image.pm:723 lib/Lutim/Controller/Image.pm:750 lib/Lutim/Plugin/Helpers.pm:88
msgid "Unable to find the image: it has been deleted."
msgstr "Невозможно найти изображение: оно было удалено."
#: lib/Lutim/Controller/Image.pm:144
msgid "Unable to get counter"
msgstr "Невозможно получить счётчик"
#: themes/default/templates/about.html.ep:17
msgid ""
"Unlike many image sharing services, you don't give us rights on uploaded "
"images."
msgstr ""
"В отличие от многих сервисов публикации изображений, вы не даёте нам права "
"на переданные изображения."
#: themes/default/templates/index.html.ep:180 themes/default/templates/index.html.ep:219
msgid "Upload an image with its URL"
msgstr "Загрузить изображение с URL"
#: themes/default/templates/myfiles.html.ep:125
msgid "Uploaded at"
msgstr "Загружено в"
#: themes/default/templates/stats.html.ep:6
msgid "Uploaded files by days"
msgstr "Загружено файлов по дням"
#. ($c->app->config('contact')
#: lib/Lutim/Plugin/Helpers.pm:221
msgid ""
"Uploading is currently disabled, please try later or contact the "
"administrator (%1)."
msgstr ""
"Загрузка сейчас отключена, пожалуйста, попробуйте позже или свяжитесь с "
"администратором (%1)."
#: themes/default/templates/index.html.ep:83 themes/default/templates/index.html.ep:85 themes/default/templates/myfiles.html.ep:122 themes/default/templates/partial/lutim.js.ep:72 themes/default/templates/partial/lutim.js.ep:76
msgid "View link"
msgstr "Ссылка на просмотр"
#: themes/default/templates/about.html.ep:22
msgid "What about the software which provides the service?"
msgstr "Что насчёт программного обеспечения, предоставляющего этот сервис?"
#: themes/default/templates/about.html.ep:3
msgid "What is Lutim?"
msgstr "Что такое Lutim?"
#: themes/default/templates/about.html.ep:15
msgid "Who owns rights on images uploaded on Lutim?"
msgstr "Кто обладает правами на изображения, загруженные на Lutim?"
#: 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 ""
"Да, это так! С другой стороны, согласно требованиям закона, ваш IP-адрес "
"будет сохранён при загрузке изображения. Без паники, это обычная практика на "
"всех сайтах, куда посылают файлы."
#: 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 ""
"Да, это так! С другой стороны, если вы хотите поддержать разработчика, вы "
"можете сделать это через <a href=\"https://www.tipeee.com/fiat-tux\">Tipeee</"
"a> или <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 "Вы запросили скачивание zip-архива с очень большим числом файлов."
#: 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 ""
"Вы можете, при желании, запросить, чтоб загруженные в Lutim изображения были "
"удалены после первого просмотра (либо скачивания) или по истечении "
"выбранного промежутка времени."
#: lib/Lutim/Controller/Authent.pm:27
msgid "You have been successfully logged in."
msgstr ""
#: lib/Lutim/Controller/Authent.pm:66 themes/default/templates/logout.html.ep:3
msgid "You have been successfully logged out."
msgstr ""
#: themes/default/templates/gallery.html.ep:31
msgid "Zoom in/out"
msgstr "Приблизить/отдалить"
#: themes/default/templates/about.html.ep:27
msgid "and on"
msgstr "и на"
#: themes/default/templates/about.html.ep:40
msgid "arabic translation"
msgstr "арабский перевод"
#: themes/default/templates/about.html.ep:27
msgid "core developer"
msgstr "разработчик ядра"
#: lib/Lutim.pm:348 lib/Lutim/Command/cron/stats.pm:145 lib/Lutim/Command/cron/stats.pm:159 lib/Lutim/Command/cron/stats.pm:176 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 "без ограничения времени"
#: themes/default/templates/about.html.ep:38
msgid "occitan translation"
msgstr "окситанский перевод"
#: themes/default/templates/about.html.ep:27
msgid "on"
msgstr "в"
#: themes/default/templates/about.html.ep:39
msgid "paste image to upload ability"
msgstr "paste image to upload ability"
#: themes/default/templates/about.html.ep:41
msgid "russian translation"
msgstr "русский перевод"
#: themes/default/templates/about.html.ep:36
msgid "spanish translation"
msgstr "испанский перевод"
#: themes/default/templates/about.html.ep:28
msgid "webapp developer"
msgstr "разработчик веб-приложения"

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,482 @@
/*! PhotoSwipe Default UI CSS by Dmitry Semenov | photoswipe.com | MIT license */
/*
Contents:
1. Buttons
2. Share modal and links
3. Index indicator ("1 of X" counter)
4. Caption
5. Loading indicator
6. Additional styles (root element, top bar, idle state, hidden state, etc.)
*/
/*
1. Buttons
*/
/* <button> css reset */
.pswp__button {
width: 44px;
height: 44px;
position: relative;
background: none;
cursor: pointer;
overflow: visible;
-webkit-appearance: none;
display: block;
border: 0;
padding: 0;
margin: 0;
float: right;
opacity: 0.75;
-webkit-transition: opacity 0.2s;
transition: opacity 0.2s;
-webkit-box-shadow: none;
box-shadow: none; }
.pswp__button:focus, .pswp__button:hover {
opacity: 1; }
.pswp__button:active {
outline: none;
opacity: 0.9; }
.pswp__button::-moz-focus-inner {
padding: 0;
border: 0; }
/* pswp__ui--over-close class it added when mouse is over element that should close gallery */
.pswp__ui--over-close .pswp__button--close {
opacity: 1; }
.pswp__button,
.pswp__button--arrow--left:before,
.pswp__button--arrow--right:before {
background: url(default-skin/default-skin.png) 0 0 no-repeat;
background-size: 264px 88px;
width: 44px;
height: 44px; }
@media (-webkit-min-device-pixel-ratio: 1.1), (-webkit-min-device-pixel-ratio: 1.09375), (min-resolution: 105dpi), (min-resolution: 1.1dppx) {
/* Serve SVG sprite if browser supports SVG and resolution is more than 105dpi */
.pswp--svg .pswp__button,
.pswp--svg .pswp__button--arrow--left:before,
.pswp--svg .pswp__button--arrow--right:before {
background-image: url(default-skin.svg); }
.pswp--svg .pswp__button--arrow--left,
.pswp--svg .pswp__button--arrow--right {
background: none; } }
.pswp__button--close {
background-position: 0 -44px; }
.pswp__button--share {
background-position: -44px -44px; }
.pswp__button--fs {
display: none; }
.pswp--supports-fs .pswp__button--fs {
display: block; }
.pswp--fs .pswp__button--fs {
background-position: -44px 0; }
.pswp__button--zoom {
display: none;
background-position: -88px 0; }
.pswp--zoom-allowed .pswp__button--zoom {
display: block; }
.pswp--zoomed-in .pswp__button--zoom {
background-position: -132px 0; }
/* no arrows on touch screens */
.pswp--touch .pswp__button--arrow--left,
.pswp--touch .pswp__button--arrow--right {
visibility: hidden; }
/*
Arrow buttons hit area
(icon is added to :before pseudo-element)
*/
.pswp__button--arrow--left,
.pswp__button--arrow--right {
background: none;
top: 50%;
margin-top: -50px;
width: 70px;
height: 100px;
position: absolute; }
.pswp__button--arrow--left {
left: 0; }
.pswp__button--arrow--right {
right: 0; }
.pswp__button--arrow--left:before,
.pswp__button--arrow--right:before {
content: '';
top: 35px;
background-color: rgba(0, 0, 0, 0.3);
height: 30px;
width: 32px;
position: absolute; }
.pswp__button--arrow--left:before {
left: 6px;
background-position: -138px -44px; }
.pswp__button--arrow--right:before {
right: 6px;
background-position: -94px -44px; }
/*
2. Share modal/popup and links
*/
.pswp__counter,
.pswp__share-modal {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none; }
.pswp__share-modal {
display: block;
background: rgba(0, 0, 0, 0.5);
width: 100%;
height: 100%;
top: 0;
left: 0;
padding: 10px;
position: absolute;
z-index: 1600;
opacity: 0;
-webkit-transition: opacity 0.25s ease-out;
transition: opacity 0.25s ease-out;
-webkit-backface-visibility: hidden;
will-change: opacity; }
.pswp__share-modal--hidden {
display: none; }
.pswp__share-tooltip {
z-index: 1620;
position: absolute;
background: #FFF;
top: 56px;
border-radius: 2px;
display: block;
width: auto;
right: 44px;
-webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25);
-webkit-transform: translateY(6px);
-ms-transform: translateY(6px);
transform: translateY(6px);
-webkit-transition: -webkit-transform 0.25s;
transition: transform 0.25s;
-webkit-backface-visibility: hidden;
will-change: transform; }
.pswp__share-tooltip a {
display: block;
padding: 8px 12px;
color: #000;
text-decoration: none;
font-size: 14px;
line-height: 18px; }
.pswp__share-tooltip a:hover {
text-decoration: none;
color: #000; }
.pswp__share-tooltip a:first-child {
/* round corners on the first/last list item */
border-radius: 2px 2px 0 0; }
.pswp__share-tooltip a:last-child {
border-radius: 0 0 2px 2px; }
.pswp__share-modal--fade-in {
opacity: 1; }
.pswp__share-modal--fade-in .pswp__share-tooltip {
-webkit-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0); }
/* increase size of share links on touch devices */
.pswp--touch .pswp__share-tooltip a {
padding: 16px 12px; }
a.pswp__share--facebook:before {
content: '';
display: block;
width: 0;
height: 0;
position: absolute;
top: -12px;
right: 15px;
border: 6px solid transparent;
border-bottom-color: #FFF;
-webkit-pointer-events: none;
-moz-pointer-events: none;
pointer-events: none; }
a.pswp__share--facebook:hover {
background: #3E5C9A;
color: #FFF; }
a.pswp__share--facebook:hover:before {
border-bottom-color: #3E5C9A; }
a.pswp__share--twitter:hover {
background: #55ACEE;
color: #FFF; }
a.pswp__share--pinterest:hover {
background: #CCC;
color: #CE272D; }
a.pswp__share--download:hover {
background: #DDD; }
/*
3. Index indicator ("1 of X" counter)
*/
.pswp__counter {
position: absolute;
left: 0;
top: 0;
height: 44px;
font-size: 13px;
line-height: 44px;
color: #FFF;
opacity: 0.75;
padding: 0 10px; }
/*
4. Caption
*/
.pswp__caption {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
min-height: 44px; }
.pswp__caption small {
font-size: 11px;
color: #BBB; }
.pswp__caption__center {
text-align: left;
max-width: 420px;
margin: 0 auto;
font-size: 13px;
padding: 10px;
line-height: 20px;
color: #CCC; }
.pswp__caption--empty {
display: none; }
/* Fake caption element, used to calculate height of next/prev image */
.pswp__caption--fake {
visibility: hidden; }
/*
5. Loading indicator (preloader)
You can play with it here - http://codepen.io/dimsemenov/pen/yyBWoR
*/
.pswp__preloader {
width: 44px;
height: 44px;
position: absolute;
top: 0;
left: 50%;
margin-left: -22px;
opacity: 0;
-webkit-transition: opacity 0.25s ease-out;
transition: opacity 0.25s ease-out;
will-change: opacity;
direction: ltr; }
.pswp__preloader__icn {
width: 20px;
height: 20px;
margin: 12px; }
.pswp__preloader--active {
opacity: 1; }
.pswp__preloader--active .pswp__preloader__icn {
/* We use .gif in browsers that don't support CSS animation */
background: url(preloader.gif) 0 0 no-repeat; }
.pswp--css_animation .pswp__preloader--active {
opacity: 1; }
.pswp--css_animation .pswp__preloader--active .pswp__preloader__icn {
-webkit-animation: clockwise 500ms linear infinite;
animation: clockwise 500ms linear infinite; }
.pswp--css_animation .pswp__preloader--active .pswp__preloader__donut {
-webkit-animation: donut-rotate 1000ms cubic-bezier(0.4, 0, 0.22, 1) infinite;
animation: donut-rotate 1000ms cubic-bezier(0.4, 0, 0.22, 1) infinite; }
.pswp--css_animation .pswp__preloader__icn {
background: none;
opacity: 0.75;
width: 14px;
height: 14px;
position: absolute;
left: 15px;
top: 15px;
margin: 0; }
.pswp--css_animation .pswp__preloader__cut {
/*
The idea of animating inner circle is based on Polymer ("material") loading indicator
by Keanu Lee https://blog.keanulee.com/2014/10/20/the-tale-of-three-spinners.html
*/
position: relative;
width: 7px;
height: 14px;
overflow: hidden; }
.pswp--css_animation .pswp__preloader__donut {
-webkit-box-sizing: border-box;
box-sizing: border-box;
width: 14px;
height: 14px;
border: 2px solid #FFF;
border-radius: 50%;
border-left-color: transparent;
border-bottom-color: transparent;
position: absolute;
top: 0;
left: 0;
background: none;
margin: 0; }
@media screen and (max-width: 1024px) {
.pswp__preloader {
position: relative;
left: auto;
top: auto;
margin: 0;
float: right; } }
@-webkit-keyframes clockwise {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); }
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg); } }
@keyframes clockwise {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); }
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg); } }
@-webkit-keyframes donut-rotate {
0% {
-webkit-transform: rotate(0);
transform: rotate(0); }
50% {
-webkit-transform: rotate(-140deg);
transform: rotate(-140deg); }
100% {
-webkit-transform: rotate(0);
transform: rotate(0); } }
@keyframes donut-rotate {
0% {
-webkit-transform: rotate(0);
transform: rotate(0); }
50% {
-webkit-transform: rotate(-140deg);
transform: rotate(-140deg); }
100% {
-webkit-transform: rotate(0);
transform: rotate(0); } }
/*
6. Additional styles
*/
/* root element of UI */
.pswp__ui {
-webkit-font-smoothing: auto;
visibility: visible;
opacity: 1;
z-index: 1550; }
/* top black bar with buttons and "1 of X" indicator */
.pswp__top-bar {
position: absolute;
left: 0;
top: 0;
height: 44px;
width: 100%; }
.pswp__caption,
.pswp__top-bar,
.pswp--has_mouse .pswp__button--arrow--left,
.pswp--has_mouse .pswp__button--arrow--right {
-webkit-backface-visibility: hidden;
will-change: opacity;
-webkit-transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1);
transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1); }
/* pswp--has_mouse class is added only when two subsequent mousemove events occur */
.pswp--has_mouse .pswp__button--arrow--left,
.pswp--has_mouse .pswp__button--arrow--right {
visibility: visible; }
.pswp__top-bar,
.pswp__caption {
background-color: rgba(0, 0, 0, 0.5); }
/* pswp__ui--fit class is added when main image "fits" between top bar and bottom bar (caption) */
.pswp__ui--fit .pswp__top-bar,
.pswp__ui--fit .pswp__caption {
background-color: rgba(0, 0, 0, 0.3); }
/* pswp__ui--idle class is added when mouse isn't moving for several seconds (JS option timeToIdle) */
.pswp__ui--idle .pswp__top-bar {
opacity: 0; }
.pswp__ui--idle .pswp__button--arrow--left,
.pswp__ui--idle .pswp__button--arrow--right {
opacity: 0; }
/*
pswp__ui--hidden class is added when controls are hidden
e.g. when user taps to toggle visibility of controls
*/
.pswp__ui--hidden .pswp__top-bar,
.pswp__ui--hidden .pswp__caption,
.pswp__ui--hidden .pswp__button--arrow--left,
.pswp__ui--hidden .pswp__button--arrow--right {
/* Force paint & create composition layer for controls. */
opacity: 0.001; }
/* pswp__ui--one-slide class is added when there is just one item in gallery */
.pswp__ui--one-slide .pswp__button--arrow--left,
.pswp__ui--one-slide .pswp__button--arrow--right,
.pswp__ui--one-slide .pswp__counter {
display: none; }
.pswp__element--disabled {
display: none !important; }
.pswp--minimal--dark .pswp__top-bar {
background: none; }

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 B

View File

@@ -0,0 +1 @@
<svg width="264" height="88" viewBox="0 0 264 88" xmlns="http://www.w3.org/2000/svg"><title>default-skin 2</title><g fill="none" fill-rule="evenodd"><g><path d="M67.002 59.5v3.768c-6.307.84-9.184 5.75-10.002 9.732 2.22-2.83 5.564-5.098 10.002-5.098V71.5L73 65.585 67.002 59.5z" id="Shape" fill="#fff"/><g fill="#fff"><path d="M13 29v-5h2v3h3v2h-5zM13 15h5v2h-3v3h-2v-5zM31 15v5h-2v-3h-3v-2h5zM31 29h-5v-2h3v-3h2v5z" id="Shape"/></g><g fill="#fff"><path d="M62 24v5h-2v-3h-3v-2h5zM62 20h-5v-2h3v-3h2v5zM70 20v-5h2v3h3v2h-5zM70 24h5v2h-3v3h-2v-5z"/></g><path d="M20.586 66l-5.656-5.656 1.414-1.414L22 64.586l5.656-5.656 1.414 1.414L23.414 66l5.656 5.656-1.414 1.414L22 67.414l-5.656 5.656-1.414-1.414L20.586 66z" fill="#fff"/><path d="M111.785 65.03L110 63.5l3-3.5h-10v-2h10l-3-3.5 1.785-1.468L117 59l-5.215 6.03z" fill="#fff"/><path d="M152.215 65.03L154 63.5l-3-3.5h10v-2h-10l3-3.5-1.785-1.468L147 59l5.215 6.03z" fill="#fff"/><g><path id="Rectangle-11" fill="#fff" d="M160.957 28.543l-3.25-3.25-1.413 1.414 3.25 3.25z"/><path d="M152.5 27c3.038 0 5.5-2.462 5.5-5.5s-2.462-5.5-5.5-5.5-5.5 2.462-5.5 5.5 2.462 5.5 5.5 5.5z" id="Oval-1" stroke="#fff" stroke-width="1.5"/><path fill="#fff" d="M150 21h5v1h-5z"/></g><g><path d="M116.957 28.543l-1.414 1.414-3.25-3.25 1.414-1.414 3.25 3.25z" fill="#fff"/><path d="M108.5 27c3.038 0 5.5-2.462 5.5-5.5s-2.462-5.5-5.5-5.5-5.5 2.462-5.5 5.5 2.462 5.5 5.5 5.5z" stroke="#fff" stroke-width="1.5"/><path fill="#fff" d="M106 21h5v1h-5z"/><path fill="#fff" d="M109.043 19.008l-.085 5-1-.017.085-5z"/></g></g></g></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 866 B

View File

@@ -0,0 +1,17 @@
.icon-ok:before { content: '\e800'; } /* '' */
.icon-eye:before { content: '\e801'; } /* '' */
.icon-download:before { content: '\e802'; } /* '' */
.icon-share:before { content: '\e803'; } /* '' */
.icon-trash:before { content: '\e804'; } /* '' */
.icon-bitcoin:before { content: '\e805'; } /* '' */
.icon-git:before { content: '\e806'; } /* '' */
.icon-twitter:before { content: '\e807'; } /* '' */
.icon-clipboard:before { content: '\e808'; } /* '' */
.icon-spinner:before { content: '\e809'; } /* '' */
.icon-shuffle:before { content: '\e80a'; } /* '' */
.icon-cancel:before { content: '\e80b'; } /* '' */
.icon-picture:before { content: '\e80c'; } /* '' */
.icon-file-archive:before { content: '\e80d'; } /* '' */
.icon-language:before { content: '\e80e'; } /* '' */
.icon-edit:before { content: '\e80f'; } /* '' */

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,17 @@
.icon-ok { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe800;&nbsp;'); }
.icon-eye { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe801;&nbsp;'); }
.icon-download { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe802;&nbsp;'); }
.icon-share { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe803;&nbsp;'); }
.icon-trash { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe804;&nbsp;'); }
.icon-bitcoin { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe805;&nbsp;'); }
.icon-git { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe806;&nbsp;'); }
.icon-twitter { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe807;&nbsp;'); }
.icon-clipboard { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe808;&nbsp;'); }
.icon-spinner { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe809;&nbsp;'); }
.icon-shuffle { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80a;&nbsp;'); }
.icon-cancel { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80b;&nbsp;'); }
.icon-picture { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80c;&nbsp;'); }
.icon-file-archive { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80d;&nbsp;'); }
.icon-language { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80e;&nbsp;'); }
.icon-edit { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80f;&nbsp;'); }

View File

@@ -0,0 +1,28 @@
[class^="icon-"], [class*=" icon-"] {
font-family: 'fontello';
font-style: normal;
font-weight: normal;
/* fix buttons height */
line-height: 1em;
/* you can be more comfortable with increased icons size */
/* font-size: 120%; */
}
.icon-ok { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe800;&nbsp;'); }
.icon-eye { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe801;&nbsp;'); }
.icon-download { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe802;&nbsp;'); }
.icon-share { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe803;&nbsp;'); }
.icon-trash { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe804;&nbsp;'); }
.icon-bitcoin { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe805;&nbsp;'); }
.icon-git { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe806;&nbsp;'); }
.icon-twitter { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe807;&nbsp;'); }
.icon-clipboard { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe808;&nbsp;'); }
.icon-spinner { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe809;&nbsp;'); }
.icon-shuffle { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80a;&nbsp;'); }
.icon-cancel { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80b;&nbsp;'); }
.icon-picture { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80c;&nbsp;'); }
.icon-file-archive { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80d;&nbsp;'); }
.icon-language { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80e;&nbsp;'); }
.icon-edit { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe80f;&nbsp;'); }

73
themes/default/public/css/fontello.css vendored Normal file
View File

@@ -0,0 +1,73 @@
@font-face {
font-family: 'fontello';
src: url('../font/fontello.eot?74275093');
src: url('../font/fontello.eot?74275093#iefix') format('embedded-opentype'),
url('../font/fontello.woff2?74275093') format('woff2'),
url('../font/fontello.woff?74275093') format('woff'),
url('../font/fontello.ttf?74275093') format('truetype'),
url('../font/fontello.svg?74275093#fontello') format('svg');
font-weight: normal;
font-style: normal;
}
/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */
/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */
/*
@media screen and (-webkit-min-device-pixel-ratio:0) {
@font-face {
font-family: 'fontello';
src: url('../font/fontello.svg?74275093#fontello') format('svg');
}
}
*/
[class^="icon-"]:before, [class*=" icon-"]:before {
font-family: "fontello";
font-style: normal;
font-weight: normal;
speak: none;
display: inline-block;
text-decoration: inherit;
width: 1em;
margin-right: .2em;
text-align: center;
/* opacity: .8; */
/* For safety - reset parent styles, that can break glyph codes*/
font-variant: normal;
text-transform: none;
/* fix buttons height, for twitter bootstrap */
line-height: 1em;
/* Animation center compensation - margins should be symmetric */
/* remove if not needed */
margin-left: .2em;
/* you can be more comfortable with increased icons size */
/* font-size: 120%; */
/* Font smoothing. That was taken from TWBS */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
/* Uncomment for 3D effect */
/* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
}
.icon-ok:before { content: '\e800'; } /* '' */
.icon-eye:before { content: '\e801'; } /* '' */
.icon-download:before { content: '\e802'; } /* '' */
.icon-share:before { content: '\e803'; } /* '' */
.icon-trash:before { content: '\e804'; } /* '' */
.icon-bitcoin:before { content: '\e805'; } /* '' */
.icon-git:before { content: '\e806'; } /* '' */
.icon-twitter:before { content: '\e807'; } /* '' */
.icon-clipboard:before { content: '\e808'; } /* '' */
.icon-spinner:before { content: '\e809'; } /* '' */
.icon-shuffle:before { content: '\e80a'; } /* '' */
.icon-cancel:before { content: '\e80b'; } /* '' */
.icon-picture:before { content: '\e80c'; } /* '' */
.icon-file-archive:before { content: '\e80d'; } /* '' */
.icon-language:before { content: '\e80e'; } /* '' */
.icon-edit:before { content: '\e80f'; } /* '' */

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
@font-face {
font-family: 'Henny_Penny';
font-style: normal;
font-weight: 400;
src: local('Henny Penny'), local('HennyPenny-Regular'), url(../font/hennypenny.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

View File

@@ -0,0 +1,136 @@
/* vim:set sw=4 ts=4 sts=4 ft=css expandtab: */
@media (max-width: 767px) {
body {
padding-top: 5px;
padding-bottom: 5px;
}
}
@media (min-width: 768px) {
body {
padding-bottom: 40px;
}
}
.container {
padding: 15px;
margin: 0 auto;
}
nav .container {
padding: 0;
}
.jsonly {
display: none;
}
.thumbnail {
margin-right: 8px;
}
.hennypenny {
font-family: 'Henny_Penny', cursive;
font-size: 42px;
}
.logo {
margin-right: 10px;
}
label.always-encrypt {
display: none;
}
.link_nocol,
.link_nocol:hover{
color: #000000;
text-decoration: none;
}
#install-app img {
height: 22px;
}
#install-app {
display: none;
}
.form-control[readonly] {
background-color: #FFFFFF;
}
.alert .form-group {
margin-bottom: 5px;
}
#copy-all {
margin-bottom: 8px;
}
#gallery-url {
margin-bottom: 10px;
}
.adjust-addon {
width: 42px;
}
.adjust-addon .btn {
width: 43px;
}
#tipeee-img {
margin-top: -4px;
}
#liberapay-img {
height: 21px;
line-height: 21px;
margin-top: -5.33333px;
}
.pasteZone {
position: absolute;
top: 0;
left: -100px;
z-index: -999;
height: 10000vh;
width: 0;
display: hidden;
}
.gallery figure {
margin-right: auto;
margin-left: auto;
margin-bottom: 5px;
}
@media (min-width: 1200px) {
.gallery { column-count: 4 }
}
@media (min-width: 991px) and (max-width: 1199px) {
.gallery { column-count: 3 }
}
@media (min-width: 676px) and (max-width: 990px) {
.gallery { column-count: 2 }
}
@media (max-width: 675px) {
.gallery { column-count: 1 }
}
.border-zero {
border: 0;
}
.copy-node {
width: 1px;
height: 1px;
position: 'fixed';
top: 5px;
}
.width-zero {
width: 0%;
}
.pdg-left-10 {
padding-left: 10px;
}
.spin {
font-size: 200%;
display: none;
}
#myfiles td.ellips {
max-width: 300px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
h1.ellips {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

View File

@@ -0,0 +1,31 @@
@font-face {
font-family: 'markdown';
src:url('../../font/markdown.eot?-6fnbp5');
src:url('../../font/markdown.eot?#iefix-6fnbp5') format('embedded-opentype'),
url('../../font/markdown.woff?-6fnbp5') format('woff'),
url('../../font/markdown.ttf?-6fnbp5') format('truetype'),
url('../../font/markdown.svg?-6fnbp5#markdown') format('svg');
font-weight: normal;
font-style: normal;
}
[class^="markdown-"], [class*=" markdown-"] {
font-family: 'markdown';
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.markdown-mark:before {
content: "\e600";
}
.markdown-mark-solid:before {
content: "\e601";
}

View File

@@ -0,0 +1,2 @@
.morris-hover{position:absolute;z-index:1000}.morris-hover.morris-default-style{border-radius:10px;padding:6px;color:#666;background:rgba(255,255,255,0.8);border:solid 2px rgba(230,230,230,0.8);font-family:sans-serif;font-size:12px;text-align:center}.morris-hover.morris-default-style .morris-hover-row-label{font-weight:bold;margin:0.25em 0}
.morris-hover.morris-default-style .morris-hover-point{white-space:nowrap;margin:0.1em 0}

Some files were not shown because too many files have changed in this diff Show More