Initial import

This commit is contained in:
2026-01-18 00:53:18 +00:00
parent fb78291fb1
commit 940191502e
115 changed files with 15524 additions and 0 deletions
+13
View File
@@ -0,0 +1,13 @@
<?php
class DocMeta extends Model {
protected $_classes = [
"document" => "Document",
"metadata" => "MetaType"
];
}
+17
View File
@@ -0,0 +1,17 @@
<?php
class DocProduct extends Model {
protected $_classes = [
"document" => "Document",
"product" => "Product"
];
protected $_model = [
"id" => [MODEL_SERIAL],
"created" => [MODEL_BIGINT, 11],
"updated" => [MODEL_BIGINT, 11],
"document" => [MODEL_OBJECT, "Document"],
"product" => [MODEL_OBJECT, "Product"]
];
}
+191
View File
@@ -0,0 +1,191 @@
<?php
class Document extends Model {
protected $_computed = [
"related" => "get_related",
"revisions" => "get_revisions",
"products" => "get_products",
"metadata" => "get_metadata",
"attachments" => "get_attachments",
];
public function get_revisions() {
return Revision::find([["document", "=", $this->id]])->orderBy("revno")->all();
}
public function get_related() {
$revs = Revision::find([["document", "=", $this->id]])->all();
$related = new Collection;
foreach ($revs as $rev) {
$q = DB::getInstance()->query("
select
id,
internal_id,
title,
subtitle,
subsubtitle
from
document
where
internal_id in (
select
distinct words.word
from
words,
revwords
where
words.id=revwords.word
and
revwords.revision=:rev
and
words.word like '%-%-%'
)", array("rev" => $rev->id));
while ($r = DB::getInstance()->nextRecord($q)) {
if ($r->id != $this->id) {
$related->push(new Document($r->id));
}
}
}
return $related;
}
public function overview_md() {
return \Michelf\Markdown::defaultTransform($this->overview);
}
public function on_delete() {
DB::getInstance()->query("delete from docproduct where document=:id", ["id" => $this->id]);
}
private $_products = null;
public function get_products() {
if ($this->_products == null) {
$this->_products = new Collection;
$dpl = DocProduct::find([["document", "=", $this->id]])->all();
foreach ($dpl as $dp) {
$dp->load("product");
$this->_products->push($dp->product);
}
}
return $this->_products;
}
public function duplicate() {
$newdoc = new Document();
$newdoc->title = $this->title;
$newdoc->subtitle = $this->subtitle;
$newdoc->subsubtitle = $this->subsubtitle;
$newdoc->overview = $this->overview;
$newdoc->internal_id = $this->internal_id;
$newdoc->owner = $this->owner;
$newdoc->year = $this->year;
$newdoc->month = $this->month;
$newdoc->save();
$dpl = DocProduct::find([["document", "=", $this->id]])->all();
foreach ($dpl as $dp) {
$ndp = new DocProduct();
$ndp->document = $newdoc->id;
$ndp->product = $dp->product;
$ndp->save();
}
return $newdoc;
}
public function remove_product($id) {
$dp = DocProduct::find([["document", "=", $this->id], ["product", "=", $id]])->first();
if ($dp) {
$dp->delete();
}
}
public function set_metadata($metadata, $value) {
$m = DocMeta::find([["document", "=", $this->id], ["metadata", "=", $metadata]])->first();
if (!$m) {
$m = new DocMeta();
$m->document = $this->id;
$m->metadata = $metadata;
}
$m->data = $value;
$m->save();
return $m->id;
}
public function get_metadata() {
return DocMeta::find([["document", "=", $this->id]])->all();
}
public function remove_metadata($metadata) {
$m = DocMeta::find([["document", "=", $this->id], ["metadata", "=", $metadata]])->first();
if ($m) {
$m->delete();
}
}
public function get_metadata_by_id($metadata) {
$m = DocMeta::find([["document", "=", $this->id], ["metadata", "=", $metadata]])->first();
if (!$m) {
return "";
}
return $m->data;
}
public function guess_docid() {
$text = $this->title . " " . $this->subtitle . " " . $this->subsubtitle;
$text .= $this->overview;
$words = $this->get_words($text);
return IDMatch::find_docid($words)[0];
}
function get_words($text) {
$text = str_replace("\r", " ", $text);
$text = str_replace("\n\n", "\n", $text);
$text = str_replace("\n\n", "\n", $text);
$text = str_replace("\n\n", "\n", $text);
$text = str_replace("\n\n", "\n", $text);
$text = str_replace("\n", " ", $text);
$text = str_replace("\"", "", $text);
$text = str_replace(",", " ", $text);
$text = str_replace("", "-", $text);
$text = str_replace("~", "-", $text);
$text = str_replace("--", "-", $text);
$text = preg_replace('/([^a-zA-Z\-0-9]+)/', ' ', $text);
//$text = preg_replace("/([A-Za-z])(- )/", '$1', $text);
$words = preg_split('/\s+/', $text);
return $words;
}
function get_attachments() {
$ap = ROOT . "/attachments/" . $this->id;
$files = new Collection;
if (!file_exists($ap)) {
return $files;
}
if (!is_dir($ap)) {
return $files;
}
$dir = opendir($ap);
while ($f = readdir($dir)) {
if (substr($f, 0, 1) == ".") continue;
$f = new File($ap . "/" . $f);
$files->push($f);
}
return $files;
}
}
+54
View File
@@ -0,0 +1,54 @@
<?php
class IDMatch extends Model {
public static function find_docid($words) {
if (!is_array($words)) {
$words = IDMatch::get_words($words);
}
$matches = IDMatch::find()->orderBy("weight")->all();
foreach ($matches as $match) {
$preg = '/^' . $match->regex . '$/';
foreach ($words as $word) {
$word = strtoupper($word);
$word = str_replace("(", "C", $word);
$word = str_replace("=", "-", $word);
$word = str_replace("--", "-", $word);
if (preg_match($preg, $word, $m)) {
return [$m[1], @$m[2]];
}
}
}
return false;
}
public static function get_words($text) {
print("<<$text>>\n");
$text = str_replace("\r", " ", $text);
$text = str_replace("\n\n", "\n", $text);
$text = str_replace("\n\n", "\n", $text);
$text = str_replace("\n\n", "\n", $text);
$text = str_replace("\n\n", "\n", $text);
$text = str_replace("\n", " ", $text);
$text = str_replace("\"", "", $text);
$text = str_replace(",", " ", $text);
$text = str_replace("", "-", $text);
$text = str_replace("", "-", $text);
$text = str_replace("~", "-", $text);
$text = str_replace("--", "-", $text);
$text = preg_replace('/([^a-zA-Z\-0-9]+)/', ' ', $text);
print(">>$text<<\n");
//$text = preg_replace("/([A-Za-z])(- )/", '$1', $text);
$words = preg_split('/\s+/', $text);
return $words;
}
}
+11
View File
@@ -0,0 +1,11 @@
<?php
class MetaType extends Model {
protected $table = "metatypes";
public static function name($id) {
$m = new MetaType($id);
return $m->name;
}
}
+4
View File
@@ -0,0 +1,4 @@
<?php
class OCR extends Model {
}
+163
View File
@@ -0,0 +1,163 @@
<?php
class Product extends Model {
protected $_classes = [
"parent" => "Product"
];
protected $_computed = [
"documents" => "get_documents",
"children" => "get_children",
];
protected $_triggers = [
"parent" => "update_path",
"title" => "update_path",
];
private $_children = null;
public function get_children() {
$c = $this->cache_get("children");
if ($c) return $c;
if ($this->_children == null) {
$this->_children = Product::find([["parent", "=", $this->id]])->orderBy("title")->all();
}
$this->cache_set("children", $this->_children);
return $this->_children;
}
public function get_full_title() {
$tree = $this->get_tree();
$n = [];
foreach ($tree as $t) {
$n[] = $t->title;
}
$out = implode(" / ", $n);
return $out;
}
public function update_path($ppath = null) {
if ($ppath == null) {
$this->full_path = $this->get_full_title();
} else {
$this->full_path = $ppath . " / " . $this->title;
}
$this->full_path = str_replace("/ / ", "/ ", $this->full_path);
$this->save();
foreach ($this->get_children() as $child) {
$child->update_path($this->fill_path);
}
}
public function get_tree() {
$out = [];
if ($this->load("parent")) {
$p = $this->parent;
$out = $p->get_tree();
}
array_push($out, $this);
return $out;
}
public function overview_md() {
return \Michelf\Markdown::defaultTransform($this->overview);
}
public function on_delete() {
DB::getInstance()->query("delete from docproduct where product=:id", ["id" => $this->id]);
}
private $_documents = null;
public function get_documents() {
$d = $this->cache_get("documents");
if ($d) return $d;
if ($this->_documents == null) {
//$dpl = DocProduct::find([["product", "=", $this->id]])->limit(100)->all();
$dpl = DocProduct::find([["product", "=", $this->id]])->all();
$this->_documents = new Collection;
foreach ($dpl as $dp) {
if ($dp->load("document")) {
$this->_documents->push($dp->document);
}
}
$this->_documents->sort("subsubtitle", true);
$this->_documents->sort("subtitle", true);
$this->_documents->sort("title", true);
}
$this->cache_set("documents", $this->_documents);
return $this->_documents;
}
public function add_document($doc) {
$dp = new DocProduct;
$dp->product = $this->id;
$dp->document = $doc->id;
$dp->save();
}
public function meta() {
if ($this->metadata == null) {
return [];
}
return explode(",", $this->metadata);
}
public function add_meta($id, $save = true) {
$m = $this->meta();
if (!in_array($id, $m)) {
$m[] = $id;
}
$this->metadata = implode(",", $m);
if ($save) $this->save();
}
public function del_meta($id, $save = true) {
$m = $this->meta();
$o = [];
foreach ($m as $v) {
if ($v != $id) {
$o[] = $v;
}
}
$this->metadaya = implode(",", $o);
if ($save) $this->save();
}
public function documents_sorted_by_meta() {
if ($this->metadata == null) {
$meta = [];
} else {
$meta = explode(",", $this->metadata);
}
$docs = $this->get_documents();
while (count($meta) > 0) {
$mid = array_pop($meta);
$docs->sort_with_function( function($a, $b) use ($mid) {
$va = $a->get_metadata_by_id($mid);
$vb = $b->get_metadata_by_id($mid);
if ($va > $vb) return 1;
if ($va < $vb) return -1;
return 0;
});
}
return $docs;
}
}
+114
View File
@@ -0,0 +1,114 @@
<?php
class Revision extends Model {
protected $_classes = [
"document" => "Document"
];
protected $_computed = [
"body" => "get_body",
];
protected $transform = [
"info" => "json"
];
function path() {
$rs = sprintf("%011d", $this->id);
$d1 = substr($rs, 0, 2);
$d2 = substr($rs, 2, 3);
$d3 = substr($rs, 5, 3);
$d4 = substr($rs, 8, 3);
$p = sprintf("%s/pdf/%s/%s/%s/%s", ROOT, $d1, $d2, $d3, $d4);
return $p;
}
function filename() {
if ($this->document) {
$out = $this->document->internal_id;
if (($this->revno != "") && ($this->revno != "0")) {
$out .= "-";
$out .= $this->revno;
}
$out .= " ";
$out .= $this->document->title . " " . $this->document->subtitle . " " . $this->document->subsubtitle;
} else {
$out = "doc";
}
$out = trim($out);
$out.= ".pdf";
$out = str_replace(" ", "_", $out);
$out = str_replace("/", "_", $out);
return $out;
}
function create_cover() {
$p = $this->path();
$pdf = new PDF($p . "/doc.pdf");
$cover = $p . "/cover.jpg";
$pdf->extract_page(0, $cover);
}
function cover($size = null) {
$f = new File($this->path() . "/cover.jpg");
if (!$f->exists()) {
$this->create_cover();
}
if ($size == null) {
return "/cover/" . $this->id . "/cover.jpg";
}
return "/cover/" . $this->id . "/" . $size . "/cover.jpg";
}
private $_body = null;
public function get_body() {
if ($this->_body == null) {
$ocr = OCR::find([["revision", "=", $this->id]])->first();
if (!$ocr) {
return "";
}
$this->_body = $ocr->body;
}
return $this->_body;
}
public function get_page($page, $dpi = 300) {
$file = new File(sprintf("%s/pages/%04d-%d.jpg", $this->path(), $page, $dpi));
if ($file->exists()) {
return new Image($file);
}
$dir = sprintf("%s/pages", $this->path());
if (!file_exists($dir)) {
mkdir($dir, 0777);
}
$pdf = new PDF(sprintf("%s/doc.pdf", $this->path()));
$img = $pdf->extract_page($page, $file->path(), $dpi);
if ($img) {
return $img;
}
return null;
}
public function purge() {
$dir = opendir($this->path());
while ($file = readdir($dir)) {
if (str_ends_with($file, ".jpg")) {
unlink($this->path() . "/" . $file);
}
}
closedir($dir);
$dir = opendir($this->path() . "/pages");
while ($file = readdir($dir)) {
if (str_ends_with($file, ".jpg")) {
unlink($this->path() . "/pages/" . $file);
}
}
closedir($dir);
}
}
+4
View File
@@ -0,0 +1,4 @@
<?php
class Spider extends Model {
}
+4
View File
@@ -0,0 +1,4 @@
<?php
class SpiderBanned extends Model {
}
+4
View File
@@ -0,0 +1,4 @@
<?php
class SpiderDom extends Model {
}
+5
View File
@@ -0,0 +1,5 @@
<?php
class SpiderPage extends Model {
protected $table="pages";
}
+5
View File
@@ -0,0 +1,5 @@
<?php
class User extends Model {
public static $table = "users";
}