Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DRAFT] Autowiki #19897

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .github/workflows/autowiki.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Autowiki
on:
schedule:
- cron: "5 4 * * *"
workflow_dispatch:
permissions:
contents: read

jobs:
autowiki:
runs-on: ubuntu-20.04
steps:
- name: "Check for AUTOWIKI_USERNAME"
id: secrets_set
env:
ENABLER_SECRET: ${{ secrets.AUTOWIKI_USERNAME }}
run: |
unset SECRET_EXISTS
if [ -n "$ENABLER_SECRET" ]; then SECRET_EXISTS=true ; fi
echo "SECRETS_ENABLED=$SECRET_EXISTS" >> $GITHUB_OUTPUT
- name: Checkout
if: steps.secrets_set.outputs.SECRETS_ENABLED
uses: actions/checkout@v3
- name: Restore BYOND cache
if: steps.secrets_set.outputs.SECRETS_ENABLED
uses: actions/cache@v3
with:
path: ~/BYOND
key: ${{ runner.os }}-byond-${{ secrets.CACHE_PURGE_KEY }}
- name: Install rust-g
if: steps.secrets_set.outputs.SECRETS_ENABLED
run: |
sudo dpkg --add-architecture i386
sudo apt update || true
sudo apt install -o APT::Immediate-Configure=false libssl1.1:i386
bash tools/ci/install_rust_g.sh
- name: Compile and generate Autowiki files
if: steps.secrets_set.outputs.SECRETS_ENABLED
run: |
bash tools/ci/install_byond.sh
source $HOME/BYOND/byond/bin/byondsetup
tools/build/build --ci autowiki
- name: Run Autowiki
if: steps.secrets_set.outputs.SECRETS_ENABLED
env:
USERNAME: ${{ secrets.AUTOWIKI_USERNAME }}
PASSWORD: ${{ secrets.AUTOWIKI_PASSWORD }}
run: |
cd tools/autowiki
npm install
cd ../..
node tools/autowiki/autowiki.js data/autowiki_edits.txt data/autowiki_files/
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,6 @@ define_sanity_output.txt

# Unit test / coverage reports
.cache

# Misc. Node Modules
**/node_modules/*
6 changes: 6 additions & 0 deletions aurorastation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "code\__DEFINES\assemblies.dm"
#include "code\__DEFINES\assert.dm"
#include "code\__DEFINES\atmos.dm"
#include "code\__DEFINES\autowiki.dm"
#include "code\__DEFINES\auxtools.dm"
#include "code\__DEFINES\background.dm"
#include "code\__DEFINES\battle_monsters.dm"
Expand Down Expand Up @@ -1665,6 +1666,10 @@
#include "code\modules\atmospherics\components\unary\unary_base.dm"
#include "code\modules\atmospherics\components\unary\vent_pump.dm"
#include "code\modules\atmospherics\components\unary\vent_scrubber.dm"
#include "code\modules\autowiki\autowiki.dm"
#include "code\modules\autowiki\pages\_page.dm"
#include "code\modules\autowiki\pages\food_recipes.dm"
#include "code\modules\autowiki\pages\guns.dm"
#include "code\modules\awaymissions\bluespaceartillery.dm"
#include "code\modules\awaymissions\corpse.dm"
#include "code\modules\awaymissions\exile.dm"
Expand Down Expand Up @@ -3731,6 +3736,7 @@
#include "code\modules\world_api\commands\tickets.dm"
#include "code\modules\xgm\xgm_gas_data.dm"
#include "code\modules\xgm\xgm_gas_mixture.dm"
#include "code\unit_tests\autowiki.dm"
#include "code\unit_tests\chemistry_tests.dm"
#include "code\unit_tests\cooking_tests.dm"
#include "code\unit_tests\create_and_destroy.dm"
Expand Down
7 changes: 7 additions & 0 deletions code/__DEFINES/autowiki.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifdef AUTOWIKI
#define AUTOWIKI_SKIP(skip) autowiki_skip = skip
#define IS_AUTOWIKI_SKIP(datum) datum.autowiki_skip
#else
#define AUTOWIKI_SKIP(skip)
#define IS_AUTOWIKI_SKIP(datum) UNLINT(FALSE)
#endif
9 changes: 9 additions & 0 deletions code/__HELPERS/lists.dm
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@

return "[output][and_text][input[index]]"

/// Takes an empty list OR associated list and adds the item to it if it doesn't exist, or increments the count if it does exist
/proc/simple_counting_list(var/list/input, var/item)
var/name = "[item]" // index items by name; usually works fairly well for loose equality
if(name in input)
input[name]++
else
input[name] = 1
return input

//Returns a newline-separated list that counts equal-ish items, outputting count and item names, optionally with icons and specific determiners
/proc/counting_english_list(var/list/input, output_icons = TRUE, determiners = DET_NONE, nothing_text = "nothing", line_prefix = "\t", first_item_prefix = "\n", last_item_suffix = "\n", and_text = "\n", comma_text = "\n", final_comma_text = "")
var/list/counts = list() // counted input items
Expand Down
6 changes: 6 additions & 0 deletions code/__HELPERS/sorting/cmp.dm
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
/proc/cmp_text_dsc(a,b)
return sorttext(a,b)

/proc/cmp_typepaths_asc(A, B)
return sorttext("[B]","[A]")

/proc/cmp_typepaths_name_asc(atom/A, atom/B)
return sorttext(initial(A.name), initial(B.name))

/proc/cmp_embed_text_asc(a,b)
if(isdatum(a))
a = REF(a)
Expand Down
1 change: 1 addition & 0 deletions code/_compile_options.dm
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
// #define TESTING // Creates debug feedback messages and enables many optional testing procs/checks
// #define UNIT_TEST
// #define MANUAL_UNIT_TEST
// #define AUTOWIKI

#if defined(MANUAL_UNIT_TEST) && !defined(SPACEMAN_DMM) && !defined(OPENDREAM)
#warn Manual unit test is defined, remember to recomment it before PRing!
Expand Down
36 changes: 28 additions & 8 deletions code/controllers/subsystems/plants.dm
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,32 @@ SUBSYSTEM_DEF(plants)
priority = SS_PRIORITY_PLANTS
runlevels = RUNLEVELS_PLAYING

var/list/product_descs = list() // Stores generated fruit descs.
var/list/seeds = list() // All seed data stored here.
var/list/gene_tag_masks = list() // Gene obfuscation for delicious trial and error goodness.
var/list/plant_icon_cache = list() // Stores images of growth, fruits and seeds.
var/list/plant_sprites = list() // List of all harvested product sprites.
var/list/plant_product_sprites = list() // List of all growth sprites plus number of growth stages.
var/list/gene_masked_list = list() // Stores list of masked genes rather than recreating it later
var/list/plant_gene_datums = list() // Stores gene masked list as datums
/// Stores generated fruit descs.
var/list/product_descs = list()

/// All seed data stored here.
var/list/seeds = list()

/// Stores seed data based on the kitchen tag
var/list/seeds_by_kitchen_tag = list()

/// Gene obfuscation for delicious trial and error goodness.
var/list/gene_tag_masks = list()

/// Stores images of growth, fruits and seeds.
var/list/plant_icon_cache = list()

/// List of all harvested product sprites.
var/list/plant_sprites = list()

/// List of all growth sprites plus number of growth stages.
var/list/plant_product_sprites = list()

/// Stores list of masked genes rather than recreating it later
var/list/gene_masked_list = list()

/// Stores gene masked list as datums
var/list/plant_gene_datums = list()


var/list/processing = list()
Expand Down Expand Up @@ -50,6 +68,8 @@ SUBSYSTEM_DEF(plants)
for(var/type in typesof(/datum/seed)-/datum/seed)
var/datum/seed/S = new type
seeds[S.name] = S
if(S.kitchen_tag)
seeds_by_kitchen_tag[S.kitchen_tag] = S
S.uid = "[seeds.len]"
S.roundstart = 1

Expand Down
5 changes: 5 additions & 0 deletions code/datums/datum.dm
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@
// Create and destroy is weird and I wanna cover my bases
var/harddel_deets_dumped = FALSE

#ifdef AUTOWIKI
/// When set to TRUE, will not be added to the autowiki
var/autowiki_skip = FALSE
#endif

/**
* Default implementation of clean-up code.
*
Expand Down
4 changes: 4 additions & 0 deletions code/game/world.dm
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ GLOBAL_PROTECT(config)

Master.Initialize(10, FALSE, TRUE)

#ifdef AUTOWIKI
setup_autowiki()
#endif

#undef RECOMMENDED_VERSION

return
Expand Down
56 changes: 56 additions & 0 deletions code/modules/autowiki/autowiki.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/// When the `AUTOWIKI` define is enabled, will generate an output file for tools/autowiki/autowiki.js to consume.
/// Autowiki code intentionally still *exists* even without the define, to ensure developers notice
/// when they break it immediately, rather than until CI or worse, call time.
#if defined(AUTOWIKI) || defined(UNIT_TESTS)
/proc/setup_autowiki()
Master.sleep_offline_after_initializations = FALSE
UNTIL(SSticker.current_state == GAME_STATE_PREGAME)

//trigger things to run the whole process
SSticker.restart_timeout = 0
SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(generate_autowiki)))
SSticker.current_state = GAME_STATE_SETTING_UP

/proc/generate_autowiki()
var/output = generate_autowiki_output()
rustg_file_write(output, "data/autowiki_edits.txt")
qdel(world)
#endif

/// Returns a string of the autowiki output file
/proc/generate_autowiki_output()
var/total_output = ""

for (var/datum/autowiki/autowiki_type as anything in subtypesof(/datum/autowiki))
var/datum/autowiki/autowiki = new autowiki_type

if(autowiki.generate_multiple)
var/output = autowiki.generate_multiple()

if (!islist(output))
CRASH("[autowiki_type] does not generate a proper output when generate_multiple is set!")

for(var/list in output)
total_output += json_encode(list) + "\n"

if(!autowiki.page)
continue

var/list/all_page_names = list()
for(var/list in output)
all_page_names += autowiki.include_template(list["title"])

total_output += json_encode(list("title" = autowiki.page, "text" = all_page_names.Join(" "))) + "\n"
continue

var/output = autowiki.generate()

if (!istext(output))
CRASH("[autowiki_type] does not generate a proper output!")

total_output += json_encode(list(
"title" = autowiki.page,
"text" = output,
)) + "\n"

return total_output
64 changes: 64 additions & 0 deletions code/modules/autowiki/pages/_page.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/// A representation of an automated wiki page.
/datum/autowiki
/// The page on the wiki to be replaced.
/// This should never be a user-facing page, like "Guide to circuits".
/// It should always be a template that only Autowiki should touch.
/// For example: "Template:Autowiki/CircuitInfo".
var/page

/// If the generation of this autowiki should call /generate_multiple(),
/// which should return a list of list(title = "Page Title", contents)
/// allowing for the generation of multiple pages in the same autowiki
var/generate_multiple = FALSE

/// Override and return the new text of the page.
/// This proc can be impure, usually to call `upload_file`.
/datum/autowiki/proc/generate()
SHOULD_CALL_PARENT(FALSE)
CRASH("[type] does not implement generate()!")

/datum/autowiki/proc/generate_multiple()
SHOULD_CALL_PARENT(FALSE)

/// Generates an auto formatted template user.
/// Your autowiki should ideally be a *lot* of these.
/// It lets wiki editors edit it much easier later, without having to enter repo.
/// Parameters will be passed in by name. That means your template should expect
/// something that looks like `{{ Autowiki_Circuit|name=Combiner|description=This combines }}`
/// Lists, which must be array-like (no keys), will be turned into a flat list with their key and a number,
/// such that list("food" = list("fruit", "candy")) -> food1=fruit|food2=candy
/// Your page should respect AUTOWIKI_SKIP, and check for this using IS_AUTOWIKI_SKIP
/datum/autowiki/proc/include_template(name, parameters)
var/template_text = "{{[name]"

var/list/prepared_parameters = list()
for (var/key in parameters)
var/value = parameters[key]
if (islist(value))
for (var/index in 1 to length(value))
prepared_parameters["[key][index]"] = "[value[index]]"
else
prepared_parameters[key] = value

for (var/parameter_name in prepared_parameters)
template_text += "|[parameter_name]="
template_text += "[prepared_parameters[parameter_name]]"

template_text += "}}"

return template_text

/// Takes an icon and uploads it to Autowiki-name.png.
/// Do your best to make sure this is unique, so it doesn't clash with other autowiki icons.
/datum/autowiki/proc/upload_icon(icon/icon, name)
// Fuck you
// We don't have this so fingers crossed LOL
// if (IsAdminAdvancedProcCall())
// return

fcopy(icon, "data/autowiki_files/[name].png")

/// Escape a parameter such that it can be correctly put inside a wiki output
/datum/autowiki/proc/escape_value(parameter)
// | is a special character in MediaWiki, and must be escaped by...using another template.
return replacetextEx("[parameter]", "|", "{{!}}")
Loading
Loading