commit a54152fcc05e0976cee8ac2a7a9a7c04284e4e6b Author: Your Name Date: Mon Oct 13 13:49:07 2025 -0400 upload diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ad3ebee --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*~ +#* +secrets/ +*.secret +*.db +*.ttf diff --git a/README.md b/README.md new file mode 100755 index 0000000..749084d --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# PHP scripts for a site-sharing website +Needs php imagemagick & sqlite modules. +Edit `config.php` to customize \ No newline at end of file diff --git a/attribution.md b/attribution.md new file mode 100644 index 0000000..fe6d4bb --- /dev/null +++ b/attribution.md @@ -0,0 +1 @@ +https://commons.wikimedia.org/wiki/File:Snowflake11_2.png diff --git a/banner.webp b/banner.webp new file mode 100755 index 0000000..5c26fb2 Binary files /dev/null and b/banner.webp differ diff --git a/captcha.php b/captcha.php new file mode 100755 index 0000000..95be8ea --- /dev/null +++ b/captcha.php @@ -0,0 +1,52 @@ +setColor( 'white'); + +/* Create a drawing object and set the font size */ +$ImagickDraw = new ImagickDraw(); + +/* Set font and font size. You can also specify /path/to/font.ttf */ +$ImagickDraw->setFont( 'captchafont.ttf' ); +$ImagickDraw->setFontSize( 25 ); + +/* Create the text */ +$alphanum = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789abcdefghijklmnopqrstuvwxyz'; +$string = substr( str_shuffle( $alphanum ), 2, 5 ); +$_SESSION['captcha_code'] = $string; +/* Create new empty image */ +$Imagick->newImage( 80, 25, $bg ); + +/* Write the text on the image */ +$Imagick->annotateImage( $ImagickDraw, 4, 20, 0, $string ); + +/* Add some swirl */ +$Imagick->swirlImage( rand(10,20) ); + +/* Create a few random lines */ +/* +$ImagickDraw->line( rand( 0, 70 ), rand( 0, 30 ), rand( 0, 70 ), rand( 0, 30 ) ); +$ImagickDraw->line( rand( 0, 70 ), rand( 0, 30 ), rand( 0, 70 ), rand( 0, 30 ) ); +$ImagickDraw->line( rand( 0, 70 ), rand( 0, 30 ), rand( 0, 70 ), rand( 0, 30 ) ); +$ImagickDraw->line( rand( 0, 70 ), rand( 0, 30 ), rand( 0, 70 ), rand( 0, 30 ) ); +$ImagickDraw->line( rand( 0, 70 ), rand( 0, 30 ), rand( 0, 70 ), rand( 0, 30 ) ); +*/ +/* Draw the ImagickDraw object contents to the image. */ +$Imagick->drawImage( $ImagickDraw ); + +/* Give the image a format */ +$Imagick->setImageFormat( 'jpg' ); +/* Send headers and output the image */ +header( "Content-Type: image/{$Imagick->getImageFormat()}" ); +echo $Imagick->getImageBlob( ); +?> diff --git a/common.php b/common.php new file mode 100755 index 0000000..593239a --- /dev/null +++ b/common.php @@ -0,0 +1,133 @@ +enableExceptions(true); +$db->query('CREATE TABLE IF NOT EXISTS "sites" ( + "id" INTEGER PRIMARY KEY AUTOINCREMENT, + "name" VARCHAR NOT NULL, + "url" VARCHAR NOT NULL, + "summary" VARCHAR NOT NULL, + "category" VARCHAR NOT NULL, + "time" DATETIME NOT NULL, + "nsfw" INTEGER NOT NULL +)'); +function submitSite($name, $url, $summary, $category) { + global $db; + $stm = $db->prepare('INSERT INTO "sites" ("name", "url", "summary", "category", "time", "nsfw") VALUES (?,?,?,?,?,?)'); + $date = date('Y-m-d H:i:s'); + $nsfw = 0; + $stm->bindParam(1, $name); + $stm->bindParam(2, $url); + $stm->bindParam(3, $summary); + $stm->bindParam(4, $category); + $stm->bindParam(5, $date); + $stm->bindParam(6, $nsfw); + return $stm->execute(); +} +function getRowCount($cat=null) { + global $db; + if ($cat) { + $stm = $db->prepare('SELECT COUNT(*) as count FROM "sites" WHERE "category" = ? ;'); + $stm->bindParam(1, $cat); + $results = $stm->execute(); + } else { + $stm = $db->prepare('SELECT COUNT(*) as count FROM "sites";'); + $results = $stm->execute(); + } + $row = $results->fetchArray(); + return intval($row['count']); +} +function getRandom() { + global $db; + $results = $db->query('SELECT * FROM "sites" ORDER BY RANDOM() LIMIT 1;'); + $row = $results->fetchArray(); + return $row['url']; +} +function renderPage($page=1, $cat) { + global $db; + global $manage; + $no = ($page-1) * 15; + if ($cat) { + $stm = $db->prepare('SELECT * FROM "sites" WHERE "category" = ? ORDER BY "time" DESC LIMIT 15 OFFSET ? ;'); + $stm->bindParam(1, $cat); + $stm->bindParam(2, $no); + $results = $stm->execute(); + } else { + $stm = $db->prepare('SELECT * FROM "sites" ORDER BY "time" DESC LIMIT 15 OFFSET ? ;'); + $stm->bindParam(1, $no); + $results = $stm->execute(); + } + while ($row = $results->fetchArray()) { + if ($row["nsfw"]) { + echo(""); + } else { + echo(""); + } + for ($i=1; $i < 5; $i++) { + echo(""); + if ($i == 1) { + if ($manage) { + echo ("

[Delete]"); + echo (" [+ NSFW]"); + echo (" [- NSFW]"); + echo (" [Blacklist]

"); + } + $url = parse_url($row[$i + 1]); + if ($url['scheme'] == 'https' || $url['scheme'] == 'http') { + echo(' '); + } else { + echo("(" . $url['scheme'] . ")"); + } + echo(' ' . $row[$i] . ' '); + if ($row["nsfw"]) { + echo("(NSFW)"); + } + } elseif ($i ==2) { + echo($row[$i+1]); + } elseif ($i ==3) { + $name = constant("categories")[$row[$i + 1]]; + echo("" . $name . ""); + } else { + echo($row[$i+1]); + } + echo(""); + } + echo(""); + } +} +# manage stuff +function deleteSite($id) { + global $db; + $stm = $db->prepare('DELETE FROM "sites" WHERE id = ?;'); + $stm->bindParam(1, $id); + return $stm->execute(); +} +function markSiteNSFW($id, $nsfw) { + global $db; + $stm = $db->prepare('UPDATE "sites" SET nsfw = ? WHERE id = ?;'); + $stm->bindParam(1, $nsfw); + $stm->bindParam(2, $id); + return $stm->execute(); +} + +if (isset($_GET["manage"])) { + $fh = fopen('secrets/password.secret','r'); + if (!$fh) { + $manage = false; + } else { + while ($hash = fgets($fh)) { + if (password_verify($_GET["manage"], $hash)) { + $manage = true; + } else { + $manage = false; + } + } + fclose($fh); + } +} else { + $manage = false; +} + + +?> + + diff --git a/config.php b/config.php new file mode 100755 index 0000000..b6bb010 --- /dev/null +++ b/config.php @@ -0,0 +1,30 @@ +- 🄯 xmpub -
Est. Oct 12, 2025'); +define("categories", array( + "blog" => "Blog", + "forum" => "Forum", + "forum-gaming" => "Forum/Gaming", + "forum-hobby" => "Forum/Hobby", + "forum-int" => "Forum/International", + "forum-anonymous" => "Forum/Anonymous", + "search" => "Search engine", + "chat" => "Chat", + "wiki" => "Wiki", + "wiki-personal" => "Wiki/Personal", + "music" => "Music", + "anime" => "Anime", + "publicserver" => "Public server", + "Other" => "Other", + "xmpp-server" => "XMPP server", + "xmpp-muc" => "XMPP room", + "irc" => "IRC", + "matrix-room" => "Matrix room", + "other-nothttp" => "Other (nonhttp)" +)); + +?> + diff --git a/css/img/bg.png b/css/img/bg.png new file mode 100755 index 0000000..c691758 Binary files /dev/null and b/css/img/bg.png differ diff --git a/css/img/paper.webp b/css/img/paper.webp new file mode 100755 index 0000000..1b5e91b Binary files /dev/null and b/css/img/paper.webp differ diff --git a/css/main.css b/css/main.css new file mode 100755 index 0000000..82fc87a --- /dev/null +++ b/css/main.css @@ -0,0 +1,107 @@ +html { + display: table; + font-family: "MS Gothic"; + margin: auto; + background-color: #a9f; + background-image: url("/css/img/bg.png"); + background-size: 100px 100px; +} + +body { + vertical-align: middle; + width: 90vw; + padding: 15px; + background-color: #fcc; + border: 2px outset #fee; + box-shadow: 5px 5px; + text-align: center; +} + +hr { + border: 1px inset #ecc; +} +.banner { + border: 2px inset #c99; + margin-bottom: 10px; +} +.about { + background-color: lightyellow; + border: 1px dashed black; + background-image: url("/css/img/paper.webp"); + background-blend-mode: multiply; + margin-top: 10px; + margin-bottom: 10px; + display: inline-block; + padding: 5px; +} +.pages { + background-color: #999; + border: 1px solid white; + color: yellow; + margin-top: 10px; + margin-bottom: 10px; +} + +table { + margin: 0px auto; + border-collapse: collapse; + border: inset #3bb; + background-color: #eef; +} +.captchacontainer { + border: 1px solid #999; + padding: 5px; + border-radius: 3px; + background-color: white; + margin: auto; + display: inline-block; + text-align: center; +} +.captcha { + border: 2px inset #999; + border-radius: 3px; + margin-bottom: 5px; +} +tr, td, th { + padding: 5px; +} + + + +td { + border-right: 1px solid #999; + border-bottom: 1px solid #999; +} +tr:nth-child(even) { + background-color: #ffe; +} +th { + border-bottom: 1px solid #177; + background-color: #9f9; + border-right: 1px solid #000; +} +.siteicon { + height: 32px; + width: 32px; + float: left; + margin-right: 10px; + border: 2px inset black; +} +button, input[type=submit] { + border-radius: 2px; + background-color: #EEFFFF; + border: 2px outset #33AAAA; +} +input[type=text] { + background-color: #fcf; + border: 1px inset #black; +} +select { + background-color: #fcf; +} +.nsfw { + background-color: #f99; +} +.selectedpage { + background-color: #ef9; +} diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..ae727fe Binary files /dev/null and b/favicon.ico differ diff --git a/index.php b/index.php new file mode 100755 index 0000000..8a7f1e6 --- /dev/null +++ b/index.php @@ -0,0 +1,44 @@ + + + + + <?php echo constant("sitename"); ?> + + +
+
+

lets you discover and share niche, non-corporate, hobby websites with others by submitting them to our database.
It's intended to help small forum operators, blog authors, and anyone else with a small website recieve traffic without having to market their site.

+
+
+ + + + + + + + +
namesummarycategoryadded
+
+ + + + +
+
+ + + + + + diff --git a/manage.php b/manage.php new file mode 100755 index 0000000..9259f81 --- /dev/null +++ b/manage.php @@ -0,0 +1,35 @@ + diff --git a/pagination.php b/pagination.php new file mode 100755 index 0000000..a2dc3ef --- /dev/null +++ b/pagination.php @@ -0,0 +1,83 @@ +"); +} + +function nextButton($params) { + echo(""); +} + +function pageLinks() { + global $page; + global $cat; + for ($i=0; $i < (intval(getRowCount($cat)/14)+1); $i++) { + if ($page == $i+1) { + echo(""); + } else { + echo(""); + } + echo("" . $i + 1 . ""); + } +} + +function pageButtons() { + global $cat; + global $page; + if (1 < $page) { + backButton(params($page-1)); + } + pageLinks(); + if ($page < intval(getRowCount($cat)/14)+1) { + nextButton(params($page+1)); + } +} + +?> diff --git a/password.sh b/password.sh new file mode 100755 index 0000000..1517d1e --- /dev/null +++ b/password.sh @@ -0,0 +1,3 @@ +#!/bin/sh +php -r "echo password_hash('$1', PASSWORD_BCRYPT);" > secrets/password.secret + diff --git a/random.php b/random.php new file mode 100755 index 0000000..26c813b --- /dev/null +++ b/random.php @@ -0,0 +1,15 @@ + + + + '); +?> + Redirecting + + +

redirecting you to a random site...

+ + + diff --git a/rules.php b/rules.php new file mode 100755 index 0000000..ebb1c1e --- /dev/null +++ b/rules.php @@ -0,0 +1,28 @@ + + + + +<?php echo constant("sitename"); ?> | Rules + + +

Rules

+
+
  • Tor/i2p hidden services are not allowed.
  • +
  • Broken or dead URLs will be rejected. This one's obvious.
  • +
  • Sites that require JavaScript to access content or post will be rejected. Sorry. The point of this list is to generate a user-friendly list of sites.
  • + + + +
  • Imageboard websites are not allowed. Textboards, however, are. Reasoning is that imageboards are popping up all the time just to go down a week or month later.
  • +
  • Sites with little content will be rejected. This rule does not apply to forums, unless the forum software is incorrectly configured or broken, or there are no posts. I will be liberal about the enforcement about this rule and say that the minimum amount of content your site should have is at least one paragraph.
  • +
  • Sites with offensive or upsetting content will be rejected. Edginess is fine, but gore/nsfl will not fly. Sensitive websites will be labelled.
  • +
  • Most importantly, have fun. I don't wanna be antagonistic or rain on anyone's parade with these rules. And I'll never talk down to you or be mean to you on purpose. It can be assumed that if a site doesn't break any of these rules it's okay, but if I find something objectable about your site, I will try to give you some forewarning before just removing it outright. +
  • + + + diff --git a/submit.php b/submit.php new file mode 100755 index 0000000..25ae2ab --- /dev/null +++ b/submit.php @@ -0,0 +1,118 @@ + (Try putting https:// or http:// at the beginning)"); + session_destroy(); + die(); + } + $tld = end(explode(".", parse_url($url, PHP_URL_HOST))); + if ($tld == "onion" || $tld == "i2p") { + echo("Hidden services are not allowed"); + session_destroy(); + die(); + } + if (in_array(parse_url($url, PHP_URL_HOST), constant("bannedhosts"))) { + echo("Blacklisted host, sorry"); + session_destroy(); + die(); + } + if (!array_key_exists($category, constant("categories"))) { + echo("You submitted an invalid category."); + session_destroy(); + die(); + } + $name = htmlspecialchars($name); + $url = htmlspecialchars($url); + $summary = htmlspecialchars($summary); + if (70 < strlen($name)) { + echo("Name too long"); + session_destroy(); + die(); + } + if (100 < strlen($url)) { + echo("URL too long"); + session_destroy(); + die(); + } + if (70 < strlen($summary)) { + echo("Summary too long"); + session_destroy(); + die(); + } + if (100 < strlen($category)) { + echo("Category too long"); + session_destroy(); + die(); + } + require 'common.php'; + if (submitSite($name, $url, $summary, $category)) { + session_destroy(); + echo("SiteShare | Success

    Your site was submitted. Click here to go back to the homepage.

    "); + die(); + } else { + echo("Error"); + session_destroy(); + die(); + } +} +?> + + + +<?php echo constant("sitename"); ?> | Submit + + +

    Submit Site

    +
    +

    ! Please check out the rules before submitting.

    +
    +
    + + + + + +
    Name 40c
    URL 100c +
    Summary 70c +
    Category
    Captcha
    (Case-insensitive)

    +
    +
    +

    +

  • Wiki - Personal is for wikis with a single editor.
  • +
  • Forum - International is for forums where multiple languages are spoken.
  • +
  • Note: If your site is for a server for another protocol like a game server, pubnix, IRC, or Gemini/Gopher, categorize it as "Public server". Note that non-HTTP links are allowed, but please categorize them as Other (Not HTTP) if there's not a category for them already.
  • +

    + + + +