Compare commits
16 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
20ab0b03f9 | ||
![]() |
d06ab8ab1a | ||
![]() |
56e607c04a | ||
![]() |
9f605bb12f | ||
![]() |
1a657aac2d | ||
![]() |
fb64ad895c | ||
![]() |
530e3c8ce2 | ||
![]() |
31ea532523 | ||
![]() |
53421bcae0 | ||
![]() |
cef1650686 | ||
![]() |
bc9f84a64c | ||
![]() |
d51fd4e1f4 | ||
![]() |
c7d14040b3 | ||
![]() |
b5303781d6 | ||
![]() |
ebe2b80e87 | ||
![]() |
a3c02b057d |
12 changed files with 218 additions and 62 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -7,3 +7,6 @@ assets/
|
||||||
templates/
|
templates/
|
||||||
lists/
|
lists/
|
||||||
vendor/
|
vendor/
|
||||||
|
*~
|
||||||
|
filespread.ini
|
||||||
|
*.sum
|
13
README.md
13
README.md
|
@ -14,7 +14,7 @@ npm install
|
||||||
composer install
|
composer install
|
||||||
```
|
```
|
||||||
|
|
||||||
Make sure you have gulp installed on your system and run
|
Make sure you have gulp and the Dart SDK installed on your system and run
|
||||||
|
|
||||||
```
|
```
|
||||||
gulp sass
|
gulp sass
|
||||||
|
@ -24,6 +24,10 @@ gulp sass
|
||||||
gulp coffee
|
gulp coffee
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
gulp dart
|
||||||
|
```
|
||||||
|
|
||||||
Create the folders `templates`, `assets` and `lists` and make sure that the server can write in these folders.
|
Create the folders `templates`, `assets` and `lists` and make sure that the server can write in these folders.
|
||||||
|
|
||||||
Finally remove the example files.
|
Finally remove the example files.
|
||||||
|
@ -34,4 +38,9 @@ Filespread is licensed under the MIT license.
|
||||||
|
|
||||||
# Contributing
|
# Contributing
|
||||||
|
|
||||||
Please refer to the [Contributing Guidlines](https://mmk2410.org/contribute/)
|
1. Fork it
|
||||||
|
2. Create a feature branch with a meaningful name (`git checkout -b my-new-feature`)
|
||||||
|
3. Add yourself to the CONTRIBUTORS file
|
||||||
|
4. Commit your changes (`git commit -am 'Add some feature'`)
|
||||||
|
5. Push to your branch (`git push origin my-new-feature`)
|
||||||
|
6. Create a new pull request
|
||||||
|
|
|
@ -10,3 +10,6 @@ timezone = "UTC"
|
||||||
email = "example@example.com"
|
email = "example@example.com"
|
||||||
; name which is given as a sender name
|
; name which is given as a sender name
|
||||||
name = "John"
|
name = "John"
|
||||||
|
; reply address
|
||||||
|
; if not set, the values above will be used
|
||||||
|
reply = ""
|
|
@ -4,6 +4,7 @@
|
||||||
gulp = require 'gulp'
|
gulp = require 'gulp'
|
||||||
coffee = require 'gulp-coffee'
|
coffee = require 'gulp-coffee'
|
||||||
sass = require 'gulp-sass'
|
sass = require 'gulp-sass'
|
||||||
|
dart = require 'gulp-dart'
|
||||||
|
|
||||||
gulp.task 'coffee', ->
|
gulp.task 'coffee', ->
|
||||||
gulp.src './res/js/*.coffee'
|
gulp.src './res/js/*.coffee'
|
||||||
|
@ -15,6 +16,15 @@ gulp.task 'sass', ->
|
||||||
.pipe sass()
|
.pipe sass()
|
||||||
.pipe gulp.dest './res/css/'
|
.pipe gulp.dest './res/css/'
|
||||||
|
|
||||||
|
gulp.task 'dart', ->
|
||||||
|
gulp.src './res/dart/*.dart'
|
||||||
|
.pipe dart {
|
||||||
|
"dest": "./res/dart/",
|
||||||
|
"minify": "true",
|
||||||
|
}
|
||||||
|
.pipe gulp.dest './res/dart/'
|
||||||
|
|
||||||
gulp.task 'default', ->
|
gulp.task 'default', ->
|
||||||
gulp.watch './res/js/*.coffee', ['coffee']
|
gulp.watch './res/js/*.coffee', ['coffee']
|
||||||
gulp.watch './res/css/*.sass', ['sass']
|
gulp.watch './res/css/*.sass', ['sass']
|
||||||
|
gulp.watch './res/dart/*.dart', ['dart']
|
||||||
|
|
|
@ -68,6 +68,7 @@
|
||||||
<p>Change the text of the email if you want.</p>
|
<p>Change the text of the email if you want.</p>
|
||||||
<p>Title:</p><input id="mailtitle" name="title" class="itextfield" />
|
<p>Title:</p><input id="mailtitle" name="title" class="itextfield" />
|
||||||
<p>Text:</p><textarea id="mailtext" name="text" class="itextarea"></textarea>
|
<p>Text:</p><textarea id="mailtext" name="text" class="itextarea"></textarea>
|
||||||
|
<p><input type="checkbox" class="icheckbox" id="nofile" />Send without file</p>
|
||||||
<p>Filename:</p><input id="filename" name="filename" class="itextfield" />
|
<p>Filename:</p><input id="filename" name="filename" class="itextfield" />
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -171,5 +172,6 @@
|
||||||
|
|
||||||
<script src="./res/js/jquery-2.1.4.min.js"></script>
|
<script src="./res/js/jquery-2.1.4.min.js"></script>
|
||||||
<script src="./res/js/main.js"></script>
|
<script src="./res/js/main.js"></script>
|
||||||
|
<script async src="./res/dart/main.dart.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"gulp": "^3.9.1",
|
"gulp": "^3.9.1",
|
||||||
"gulp-coffee": "^2.3.1",
|
"gulp-coffee": "^2.3.1",
|
||||||
|
"gulp-dart": "^0.2.4",
|
||||||
"gulp-sass": "^2.1.0",
|
"gulp-sass": "^2.1.0",
|
||||||
"node-sass": "^3.4.2"
|
"node-sass": "^3.4.2"
|
||||||
},
|
},
|
||||||
|
|
|
@ -163,6 +163,12 @@ input.button
|
||||||
.itextarea:focus
|
.itextarea:focus
|
||||||
@extend .itextfield
|
@extend .itextfield
|
||||||
|
|
||||||
|
.icheckbox
|
||||||
|
margin: 0
|
||||||
|
padding: 0
|
||||||
|
margin-right: 10px
|
||||||
|
vertical-align: sub
|
||||||
|
|
||||||
/* FILESPREAD */
|
/* FILESPREAD */
|
||||||
|
|
||||||
.edit_template
|
.edit_template
|
||||||
|
@ -180,6 +186,11 @@ input.button
|
||||||
.remove_list
|
.remove_list
|
||||||
display: none
|
display: none
|
||||||
|
|
||||||
|
#addresses
|
||||||
|
max-height: 200px
|
||||||
|
overflow-x: hidden
|
||||||
|
overflow-y: auto
|
||||||
|
|
||||||
/* FORM */
|
/* FORM */
|
||||||
form
|
form
|
||||||
margin-top: 20px
|
margin-top: 20px
|
||||||
|
|
23
res/dart/.gitignore
vendored
Normal file
23
res/dart/.gitignore
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# Files and directories created by pub
|
||||||
|
.packages
|
||||||
|
.pub/
|
||||||
|
build/
|
||||||
|
packages
|
||||||
|
# Remove the following pattern if you wish to check in your lock file
|
||||||
|
pubspec.lock
|
||||||
|
|
||||||
|
# Files created by dart2js
|
||||||
|
*.dart.js
|
||||||
|
*.part.js
|
||||||
|
*.js.deps
|
||||||
|
*.js.map
|
||||||
|
*.info.json
|
||||||
|
|
||||||
|
# Directory created by dartdoc
|
||||||
|
doc/api/
|
||||||
|
|
||||||
|
# JetBrains IDEs
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
83
res/dart/main.dart
Normal file
83
res/dart/main.dart
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
// Copyright (c) 2016 - 2017, Marcel Kapfer (mmk2410).
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
/// frontend code for filespread, a simple file over email spreading web app.
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:html';
|
||||||
|
|
||||||
|
/// main method with click listners.
|
||||||
|
void main() {
|
||||||
|
// send mail listener
|
||||||
|
querySelector("#send").onClick.listen(sendMail);
|
||||||
|
|
||||||
|
// save address list listner
|
||||||
|
querySelector("#save-addresses").onClick.listen(saveAddresses);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// function for calling the backend to send mails.
|
||||||
|
void sendMail(MouseEvent event) {
|
||||||
|
InputElement title = querySelector("#mailtitle");
|
||||||
|
InputElement text = querySelector("#mailtext");
|
||||||
|
InputElement filename = querySelector("#filename");
|
||||||
|
InputElement addresslist = querySelector("#address_list");
|
||||||
|
CheckboxInputElement nofile = querySelector("#nofile");
|
||||||
|
|
||||||
|
Map data = {
|
||||||
|
"title": title.value,
|
||||||
|
"body": text.value,
|
||||||
|
"filename": filename.value,
|
||||||
|
"list": addresslist.value,
|
||||||
|
"nofile": nofile.checked
|
||||||
|
};
|
||||||
|
|
||||||
|
String url = "res/php/sendmail.php?data=${JSON.encode(data)}";
|
||||||
|
|
||||||
|
HttpRequest.getString(url).then((String response) {
|
||||||
|
if (response == "0") {
|
||||||
|
window.alert("Mails successfully sent.");
|
||||||
|
} else {
|
||||||
|
window.alert("Failed to send mail.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// function to update the addresses list in the backend.
|
||||||
|
void saveAddresses(MouseEvent event) {
|
||||||
|
TextAreaElement addresses = querySelector("#edit-addresses");
|
||||||
|
SelectElement list = querySelector("#edit-address-list");
|
||||||
|
|
||||||
|
List<String> addressesList = new List();
|
||||||
|
|
||||||
|
addresses.value.split("\n").forEach((String address) {
|
||||||
|
if (address.isNotEmpty) addressesList.add(address);
|
||||||
|
});
|
||||||
|
|
||||||
|
Map data = {"list": list.value, "addresses": addressesList};
|
||||||
|
|
||||||
|
String url = "res/php/savelist.php";
|
||||||
|
|
||||||
|
HttpRequest.postFormData(url, {"data": JSON.encode(data)}).then((HttpRequest response) {
|
||||||
|
if (response.responseText == "0") {
|
||||||
|
window.alert("Addresses sucessfully saved.");
|
||||||
|
updateAddresses(addressesList, list.value);
|
||||||
|
} else {
|
||||||
|
window.alert("Failed to save adresses.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Updated the frontend after an address change.
|
||||||
|
void updateAddresses(List<String> addresses, String list) {
|
||||||
|
SelectElement currentList = querySelector("#address_list");
|
||||||
|
|
||||||
|
if (currentList.value == list) {
|
||||||
|
DivElement addressesContainer = querySelector("#addresses");
|
||||||
|
addressesContainer.children .removeWhere((Element child) => addressesContainer.children.contains(child));
|
||||||
|
|
||||||
|
addresses.forEach((String address) {
|
||||||
|
ParagraphElement addressElement = new ParagraphElement();
|
||||||
|
addressElement.text = address;
|
||||||
|
addressesContainer.children.add(addressElement);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,16 +3,6 @@
|
||||||
# MIT License
|
# MIT License
|
||||||
|
|
||||||
main = ->
|
main = ->
|
||||||
|
|
||||||
$("#send").click ->
|
|
||||||
url = "./res/php/sendmail.php?list=" + $("#address_list").val() +
|
|
||||||
"&template=" + $("#templates_list").val()
|
|
||||||
$.get url, (data) ->
|
|
||||||
if data is "0"
|
|
||||||
alert "Mail sent!"
|
|
||||||
else
|
|
||||||
alert "Sending mail failed!"
|
|
||||||
|
|
||||||
updateAddressLists()
|
updateAddressLists()
|
||||||
|
|
||||||
updateTemplateLists()
|
updateTemplateLists()
|
||||||
|
@ -115,20 +105,6 @@ main = ->
|
||||||
$("#edit-addresses").val(text)
|
$("#edit-addresses").val(text)
|
||||||
$(".edit_address").fadeIn()
|
$(".edit_address").fadeIn()
|
||||||
|
|
||||||
$("#save-addresses").click ->
|
|
||||||
data =
|
|
||||||
list: $("#edit-address-list").val()
|
|
||||||
addresses: $("#edit-addresses").val().split '\n'
|
|
||||||
if data.addresses[data.addresses.length - 1] is ""
|
|
||||||
data.addresses.pop()
|
|
||||||
$.get "./res/php/savelist.php", {"data": data}, (data) ->
|
|
||||||
if data == "0"
|
|
||||||
alert "List sucessfully changed!"
|
|
||||||
if data.list is $("#address_list")
|
|
||||||
updateAddresss data.list
|
|
||||||
else
|
|
||||||
alert "Error while saving the edit."
|
|
||||||
|
|
||||||
$("#create-list").click ->
|
$("#create-list").click ->
|
||||||
filename = $("#create-list-name").val()
|
filename = $("#create-list-name").val()
|
||||||
if filename.substring((filename.length - 4)) isnt ".txt"
|
if filename.substring((filename.length - 4)) isnt ".txt"
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
# COPYRIGHT (c) 2016 Marcel Kapfer (mmk2410)
|
# COPYRIGHT (c) 2016-2017 Marcel Kapfer (mmk2410)
|
||||||
# MIT License
|
# MIT License
|
||||||
|
|
||||||
$content = $_GET["data"];
|
$content = json_decode($_POST["data"], true);
|
||||||
|
|
||||||
$filename = "../../lists/" . $content["list"];
|
$filename = "../../lists/" . $content["list"];
|
||||||
|
|
||||||
|
|
|
@ -2,52 +2,87 @@
|
||||||
# COPYRIGHT (c) 2016 Marcel Kapfer (mmk2410)
|
# COPYRIGHT (c) 2016 Marcel Kapfer (mmk2410)
|
||||||
# MIT License
|
# MIT License
|
||||||
|
|
||||||
|
/**
|
||||||
|
* configuration map
|
||||||
|
*/
|
||||||
$ini = parse_ini_file("../../filespread.ini");
|
$ini = parse_ini_file("../../filespread.ini");
|
||||||
|
|
||||||
date_default_timezone_set($ini["timezone"]);
|
date_default_timezone_set($ini["timezone"]);
|
||||||
|
|
||||||
require '../../vendor/autoload.php';
|
require '../../vendor/autoload.php';
|
||||||
|
|
||||||
$list = "../../lists/" . $_GET["list"];
|
/**
|
||||||
$template = "../../templates/" . $_GET["template"];
|
* main function that is executed at the beginning.
|
||||||
|
*
|
||||||
|
* @author Marcel Kapfer <marcelmichaelkapfer@gmail.com>
|
||||||
|
*
|
||||||
|
* @param $ini an configuration map.
|
||||||
|
*/
|
||||||
|
function main($ini) {
|
||||||
|
|
||||||
|
$data = json_decode($_GET["data"], true);
|
||||||
|
|
||||||
|
$list = "../../lists/" . $data["list"];
|
||||||
$addresses = file($list);
|
$addresses = file($list);
|
||||||
$content = file($template);
|
|
||||||
|
|
||||||
$email = new PHPMailer;
|
$content = $data["body"];
|
||||||
|
|
||||||
$email->setFrom($ini["email"], $ini["name"]);
|
$title = $data["title"];
|
||||||
$email->Subject = parseSubject($content);
|
|
||||||
$email->Body = parseText($content);
|
$filename = $data["filename"];
|
||||||
|
|
||||||
|
$nofile = $data["nofile"];
|
||||||
|
|
||||||
|
if ($nofile) {
|
||||||
|
$filename = "";
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($addresses as $address) {
|
foreach ($addresses as $address) {
|
||||||
$email->AddAddress($address);
|
if (sendMail($title, $content, $filename, $address, $ini) != 0) {
|
||||||
|
print "-1";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$file_to_attach = '../../assets/file.bin';
|
print "0";
|
||||||
$filename = parseFilename($content);
|
|
||||||
|
|
||||||
$email->AddAttachment($file_to_attach, $filename);
|
}
|
||||||
|
|
||||||
if (!$email->Send()) {
|
/**
|
||||||
echo "-1";
|
* function for sending the mail.
|
||||||
echo $email->ErrorInfo;
|
*
|
||||||
|
* @author Marcel Kapfer <marcelmichaelkapfer@gmail.com>
|
||||||
|
*
|
||||||
|
* @param $title the subject of the mail.
|
||||||
|
* @param $content the text of the mail.
|
||||||
|
* @param $address the receiver of the mail.
|
||||||
|
* @param $ini an configuration map.
|
||||||
|
*/
|
||||||
|
function sendMail($title, $content, $filename, $address, $ini) {
|
||||||
|
|
||||||
|
$mail = new PHPMailer;
|
||||||
|
$mail->CharSet = 'UTF-8';
|
||||||
|
|
||||||
|
$mail->setFrom($ini["email"], $ini["name"]);
|
||||||
|
$mail->Subject = $title;
|
||||||
|
$mail->Body = $content;
|
||||||
|
|
||||||
|
$mail->addAddress($address);
|
||||||
|
|
||||||
|
if (isset($ini["reply"])) {
|
||||||
|
$mail->addReplyTo($ini["reply"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($filename)) {
|
||||||
|
$mail->AddAttachment("../../assets/file.bin", $filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$mail->Send()) {
|
||||||
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
echo "0";
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseSubject($content) {
|
|
||||||
return substr($content[0], 7);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseFilename($content) {
|
main($ini);
|
||||||
return substr($content[1], 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseText($content) {
|
|
||||||
$text = substr($content[2], 6);
|
|
||||||
for ($i = 3; $i < count($content); $i++) {
|
|
||||||
$text = $text . $content[$i];
|
|
||||||
}
|
|
||||||
return $text;
|
|
||||||
}
|
|
||||||
|
|
Reference in a new issue