diff --git a/www/.htaccess b/www/.htaccess
index 6c5dbf4..3ceba7d 100644
--- a/www/.htaccess
+++ b/www/.htaccess
@@ -1,6 +1,9 @@
AddType text/plain .md
+php_value upload_max_filesize 40M
+php_value post_max_size 42M
+
RewriteEngine On
RewriteBase /
diff --git a/www/mysql_adapter.php b/www/mysql_adapter.php
index 74b990d..d358e68 100644
--- a/www/mysql_adapter.php
+++ b/www/mysql_adapter.php
@@ -4,16 +4,19 @@ use Spatie\YamlFrontMatter\YamlFrontMatter;
class MySQLAdapter {
public $raw;
+ public $data_directory;
function __construct() {
$this->raw = mysqli_connect('mysql', 'root', 'example', 'dragon_fire');
+ $this->data_directory = 'raw';
+
if (!$this->raw)
{
- echo 'Connection failed
';
- echo 'Error number: ' . mysqli_connect_errno() . '
';
- echo 'Error message: ' . mysqli_connect_error() . '
';
- die();
+ echo 'Connection failed
';
+ echo 'Error number: ' . mysqli_connect_errno() . '
';
+ echo 'Error message: ' . mysqli_connect_error() . '
';
+ die();
}
}
@@ -24,40 +27,129 @@ class MySQLAdapter {
return $stmt->get_result();
}
-
+
function _prepare_post_data($post_data) {
- if($post_data == null) {
- $post_data = [
- "found" => false
+ if($post_data == null) {
+ return [
+ "found" => false
];
}
- else {
- $post_data["found"] = true;
- $post_data["post_metadata"] = json_decode($post_data["post_metadata"]);
- }
+ $post_data["found"] = true;
+ $post_data["post_basename"] = basename($post_data["post_path"]);
+
+ $post_meta = json_decode($post_data["post_metadata"], true) ?? [];
+
+ $post_meta["title"] ??= basename($post_data["post_path"]);
+
+ if(!isset($post_meta['type'])) {
+ $type = null;
+
+ $ext = pathinfo($post_data['post_basename'], PATHINFO_EXTENSION);
+
+ if($ext == '') {
+ $type = 'directory';
+ } elseif($ext == 'md') {
+ $type = 'text/markdown';
+ }
+
+ $post_meta['type'] = $type;
+ }
+
+ $post_data["post_content"] ??= '';
+ $post_data["post_file_dir"] = '/' . $this->data_directory . $post_data["post_path"];
+
+ $post_data['post_metadata'] = $post_meta;
+
return $post_data;
}
- function save_markdown_post($post_path, $post_data) {
- $frontmatter_post = YamlFrontMatter::parse($post_data);
+ function _fill_post_descriptors($post_data) {
- $post_path = chop($post_path, '/');
- $path_depth = substr_count($post_path, "/");
+ switch(($post_data['post_metadata']['type'] ?? '')) {
+ case 'directory':
+ $readme = $this->get_post_by_path($post_data['post_path'] . '/README.md', false);
+ $post_data['readme'] = $readme;
+
+ if($readme['found']) {
+ $post_data['post_metadata']['title'] = $readme['post_metadata']['title'];
+ }
+ break;
- $post_content = $frontmatter_post->body();
- $post_metadata = $frontmatter_post->matter();
+ case 'file':
+ $post_data['descriptor'] = $this->get_post_by_path($post_data['post_path'] . '.md', false);
+ break;
+ }
- $post_metadata['type'] = 'text/markdown';
+ return $post_data;
+ }
- var_dump($post_path, $post_content, $post_metadata);
-
- $qry = "
+ function ensure_directory($directory) {
+ $data_directory = $this->data_directory . $directory;
+
+ is_dir($data_directory) || mkdir($data_directory, 0777, true);
+
+ $insert_statement = "
INSERT INTO posts
(post_path, post_path_depth, post_metadata, post_content)
VALUES
- ( ?, ?, ?, ?) AS new
- ON DUPLICATE KEY UPDATE post_metadata=new.post_metadata, post_content=new.post_content;";
+ (?, ?, ?, '') AS new
+ ON DUPLICATE KEY UPDATE post_path=new.post_path
+ ";
+
+ $json_metadata = json_encode(["type" => 'directory']);
+
+ while(strlen($directory) > 1) {
+ try {
+ echo "Inserting dir " . $directory . "\n";
+
+ $this->_exec($insert_statement, "sis",
+ $directory, substr_count($directory, '/'),
+ $json_metadata);
+
+ }
+ catch(Exception $e) {
+ }
+ $directory = dirname($directory);
+ }
+ }
+
+ function ensure_post_placeholder($post_path, $post_metadata) {
+ $post_path = chop($post_path, '/');
+ $path_depth = substr_count($post_path, "/");
+
+ $this->ensure_directory(dirname($post_path));
+
+ echo "Bumping post placeholder " . $post_path . "\n";
+
+ $qry = "
+ INSERT INTO posts
+ (post_path, post_path_depth, post_metadata, post_content)
+ VALUES
+ ( ?, ?, ?, ?) AS new
+ ON DUPLICATE KEY UPDATE post_path=new.post_path;";
+
+ $this->_exec($qry, "siss",
+ $post_path,
+ $path_depth,
+ json_encode($post_metadata),
+ '');
+ }
+
+ function create_post_entry($post_path, $post_metadata, $post_content) {
+ $post_path = chop($post_path, '/');
+ $path_depth = substr_count($post_path, "/");
+
+ $this->ensure_directory(dirname($post_path));
+
+ echo "Creating post entry " . $post_path . "\n";
+
+ $qry = "
+ INSERT INTO posts
+ (post_path, post_path_depth, post_metadata, post_content)
+ VALUES
+ ( ?, ?, ?, ?) AS new
+ ON DUPLICATE KEY UPDATE post_metadata=new.post_metadata, post_content=new.post_content;";
$this->_exec($qry, "siss",
$post_path,
@@ -66,12 +158,60 @@ class MySQLAdapter {
$post_content);
}
+ function save_markdown_post($post_path, $post_data) {
+ $frontmatter_post = YamlFrontMatter::parse($post_data);
+ $post_path = chop($post_path, '/');
+
+ $post_content = $frontmatter_post->body();
+ $post_metadata = $frontmatter_post->matter();
+
+ if(basename($post_path) == "README.md") {
+ $readme_metadata = $frontmatter_post->matter();
+ $readme_metadata['type'] = $post_metadata['readme_type'] ?? 'directory';
+
+ $this->create_post_entry(dirname($post_path), $readme_metadata, '');
+
+ $post_metadata['type'] = 'text/markdown';
+ }
+
+ $post_metadata['type'] ??= 'text/markdown';
+
+ $this->create_post_entry($post_path, $post_metadata, $post_content);
+ file_put_contents($this->data_directory . $post_path,
+ $post_data);
+
+ }
+
+ function save_file($post_path, $file_path) {
+ $post_metadata = ["type" => 'file'];
+ $post_path = chop($post_path, '/');
+
+ $this->ensure_post_placeholder($post_path, $post_metadata, '');
+
+ copy($file_path, $this->data_directory . $post_path);
+ }
+
+ function handle_upload($post_path, $file_path) {
+ $ext = pathinfo($post_path, PATHINFO_EXTENSION);
+
+ switch($ext) {
+ case "md":
+ $this->save_markdown_post($post_path, file_get_contents($file_path));
+ break;
+ default:
+ $this->save_file($post_path, $file_path);
+ }
+ }
+
function get_post_by_path($post_path, $with_subposts = true) {
$qry = "SELECT * FROM posts WHERE post_path = ?";
$post_path = chop($post_path, '/');
- $post_data = $this->_prepare_post_data($this->_exec($qry, "s", $post_path)->fetch_assoc());
+ $post_data = $this->_exec($qry, "s", $post_path)->fetch_assoc();
+ $post_data = $this->_prepare_post_data($post_data);
+
+ $post_data = $this->_fill_post_descriptors($post_data);
if($with_subposts) {
$post_data['subposts'] = $this->get_subposts_by_path($post_path);
@@ -87,7 +227,7 @@ class MySQLAdapter {
$path_depth = substr_count($path, "/");
- $qry = "SELECT post_path, post_metadata
+ $qry = "SELECT post_path, post_metadata, post_update_time
FROM posts
WHERE (post_path LIKE CONCAT(?,'/%'))
AND post_path_depth = ?