<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:dw="https://www.dreamwidth.org">
  <id>tag:dreamwidth.org,2008-04-22:10</id>
  <title>Dreamwidth Development</title>
  <subtitle>Dreamwidth Open Source Development</subtitle>
  <author>
    <name>Dreamwidth Open Source Development</name>
  </author>
  <link rel="alternate" type="text/html" href="https://dw-dev.dreamwidth.org/"/>
  <link rel="self" type="text/xml" href="https://dw-dev.dreamwidth.org/data/atom"/>
  <updated>2023-07-18T01:44:00Z</updated>
  <dw:journal username="dw_dev" type="community"/>
  <entry>
    <id>tag:dreamwidth.org,2008-04-22:10:237175</id>
    <author>
      <name>Cocoa</name>
    </author>
    <dw:poster user="momijizukamori"/>
    <link rel="alternate" type="text/html" href="https://dw-dev.dreamwidth.org/237175.html"/>
    <link rel="self" type="text/xml" href="https://dw-dev.dreamwidth.org/data/atom/?itemid=237175"/>
    <title>Auto-tidying</title>
    <published>2023-07-15T16:27:48Z</published>
    <updated>2023-07-18T01:44:00Z</updated>
    <category term="documentation"/>
    <category term="scripts"/>
    <dw:security>public</dw:security>
    <dw:reply-count>2</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='momijizukamori' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://momijizukamori.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://momijizukamori.dreamwidth.org/'&gt;&lt;b&gt;momijizukamori&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So we've required files to be tidied using &lt;code&gt;perltidy&lt;/code&gt; &lt;a href="https://dw-dev.dreamwidth.org/213572.html"&gt;since 2019&lt;/a&gt;, buuuuut I am terrible at remembering to manually do it, so! I threw together a quick'n'dirty way of automatically running tidy on commit. It's based on &lt;a href="https://prettier.io/docs/en/precommit.html#option-6-shell-script"&gt;this example from the Prettier docs&lt;/a&gt; (Prettier is like perltidy but for CSS/JS/HTML).&lt;br /&gt;&lt;br /&gt;Here's the perl variant of the script:&lt;br /&gt;&lt;pre&gt;
#!/bin/sh
FILES=$(git diff --cached --name-only --diff-filter=ACMR | sed 's| |\\ |g')
[ -z "$FILES" ] &amp;&amp; exit 0

# Prettify all selected files
echo "$FILES" | xargs tidyall

# Add back the modified/prettified files to staging
echo "$FILES" | xargs git add

exit 0
&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This also has the bonus that it only tidies files you added to your commit, so you don't end up with rogue changes in files you didn't touch because someone else forgot to tidy before a branch got merged!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;EDIT:&lt;/b&gt; &lt;span style='white-space: nowrap;'&gt;&lt;a href='https://kareila.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://kareila.dreamwidth.org/'&gt;&lt;b&gt;kareila&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; rightfully pointed out that I didn't actually specify the install instructions (they're in the linked Prettier docs but, uh, that's not that intuitive). This script should go in the file &lt;code&gt;.git/hooks/pre-commit&lt;/code&gt;, and that file needs to be executable, which you can do on the commandline by running &lt;code&gt;chmod +x .git/hooks/pre-commit&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=dw_dev&amp;ditemid=237175" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-04-22:10:217359</id>
    <author>
      <name>alexwlchan</name>
    </author>
    <dw:poster user="alexwlchan"/>
    <link rel="alternate" type="text/html" href="https://dw-dev.dreamwidth.org/217359.html"/>
    <link rel="self" type="text/xml" href="https://dw-dev.dreamwidth.org/data/atom/?itemid=217359"/>
    <title>Searching your Dreamwidth posts by more than one tag</title>
    <published>2019-11-28T20:50:44Z</published>
    <updated>2019-11-28T20:52:57Z</updated>
    <category term="scripts"/>
    <dw:security>public</dw:security>
    <dw:reply-count>5</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='alexwlchan' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://alexwlchan.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://alexwlchan.dreamwidth.org/'&gt;&lt;b&gt;alexwlchan&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I was chatting to &lt;span style='white-space: nowrap;'&gt;&lt;a href='https://cesy.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://cesy.dreamwidth.org/'&gt;&lt;b&gt;cesy&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; this evening, and we were chatting about tagging on Dreamwidth (because I've just written about how I use tags to &lt;a href="https://alexwlchan.net/2019/11/my-scanning-setup/"&gt;organise my scanned documents&lt;/a&gt;).  In particular, we were talking about ways to find posts with particular combinations of tags.&lt;br /&gt;&lt;br /&gt;As far as we both know (please correct us if we're wrong!), you can only filter your posts by a particular tag. For example, to see all of my posts tagged with "meta", I'd visit &lt;a href="https://alexwlchan.dreamwidth.org/tag/meta"&gt;https://alexwlchan.dreamwidth.org/tag/meta&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;What if you want to search by more than one tag?  For example:&lt;ul&gt;&lt;li&gt;Which posts have I tagged with &lt;em&gt;reviews&lt;/em&gt; and &lt;em&gt;quotes&lt;/em&gt;? (An AND query)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Which posts have I tagged with at least one of &lt;em&gt;person:alex&lt;/em&gt; or &lt;em&gt;person:lexie&lt;/em&gt;? (An OR query)&lt;/li&gt;&lt;/ul&gt;I decided to try writing a script for this.&lt;br /&gt;&lt;br /&gt;I already had code that uses &lt;a href="http://wiki.dwscoalition.org/wiki/index.php/XML-RPC_Protocol"&gt;the XML-RPC API&lt;/a&gt; to get all my posts (to get a backup of my Dreamwidth entries).  I added some extra filtering, and now it can search posts using the queries of the form above.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Usage&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;You need Python installed (&lt;a href="https://www.python.org/downloads/"&gt;downloads page&lt;/a&gt;). Python 2.7 or 3.x is fine; if you already have Python installed on your computer, that should be fine.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Copy the code below into a file, for example &lt;code&gt;search_dreamwidth_posts_by_tag.py&lt;/code&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Run the script with Python, for example by typing &lt;code&gt;python search_dreamwidth_posts_by_tag.py&lt;/code&gt; in a terminal.&lt;/li&gt;&lt;/ol&gt;The script will ask you for your Dreamwidth username and password (to talk to the API), and what sort of tags you want to search for.  It saves the results to a spreadsheet, for maximum nerd points.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Reusing the code&lt;/h3&gt;If you know a bit of Python, you should be able to pull out bits of this code and reuse it elsewhere -- the XML-RPC API client, downloading all your posts, checking a user's password. You could modify it to find posts by different criteria: posts within a particular date range, or posted at the weekend, or &lt;a href="https://en.wikipedia.org/wiki/Gadsby_(novel)"&gt;that don't contain the letter e&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;MIT license.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The code&lt;/h3&gt;&lt;span class="cut-wrapper"&gt;&lt;span style="display: none;" id="span-cuttag___1" class="cuttag"&gt;&lt;/span&gt;&lt;b class="cut-open"&gt;(&amp;nbsp;&lt;/b&gt;&lt;b class="cut-text"&gt;&lt;a href="https://dw-dev.dreamwidth.org/217359.html#cutid1"&gt;Code behind a cut tag&lt;/a&gt;&lt;/b&gt;&lt;b class="cut-close"&gt;&amp;nbsp;)&lt;/b&gt;&lt;/span&gt;&lt;div style="display: none;" id="div-cuttag___1" aria-live="assertive"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=dw_dev&amp;ditemid=217359" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-04-22:10:139034</id>
    <author>
      <name>Ricky Buchanan</name>
    </author>
    <dw:poster user="jeshyr"/>
    <link rel="alternate" type="text/html" href="https://dw-dev.dreamwidth.org/139034.html"/>
    <link rel="self" type="text/xml" href="https://dw-dev.dreamwidth.org/data/atom/?itemid=139034"/>
    <title>Upgraded Omnibus Script With Added Gitness!</title>
    <published>2013-04-20T06:30:38Z</published>
    <updated>2013-04-20T06:30:38Z</updated>
    <category term="scripts"/>
    <dw:security>public</dw:security>
    <dw:reply-count>1</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='jeshyr' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://jeshyr.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://jeshyr.dreamwidth.org/'&gt;&lt;b&gt;jeshyr&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Just to let folks know, the ombibus jeshyr-do-anything script at &lt;a href="http://dw-dev.dreamwidth.org/94822.html"&gt;http://dw-dev.dreamwidth.org/94822.html&lt;/a&gt; has been upgraded to cope with git.&lt;br /&gt;&lt;br /&gt;It doesn't do quite as many things as it used to, but it does all the basics and I'll add new things back in as I figure out how to do them with git.&lt;br /&gt;&lt;br /&gt;Jobs it currently handles include:&lt;br /&gt;Apache server up/down/restart&lt;br /&gt;Move between free/nonfree directory trees&lt;br /&gt;Update databases&lt;br /&gt;Upgrade your hack with github code&lt;br /&gt;Hard reset your hack to current github state&lt;br /&gt;Tidy old patching artefacts&lt;br /&gt;Show apache error logs&lt;br /&gt;&lt;br /&gt;It used to make patches and handle diffs and stuff but since that's all *so* different in git I just ripped it out and will re-add as appropriate.&lt;br /&gt;&lt;br /&gt;You can always find the code at &lt;a href="http://dw-dev.dreamwidth.org/94822.html"&gt;http://dw-dev.dreamwidth.org/94822.html&lt;/a&gt; - I won't include it here, trying to keep it just in one place or we'll end up with 27 different versions.&lt;br /&gt;&lt;br /&gt;Comments, brickbats, boquets, requests, and suggestions welcome :)&lt;br /&gt;&lt;br /&gt;Cheers,&lt;br /&gt;r&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=dw_dev&amp;ditemid=139034" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-04-22:10:133161</id>
    <author>
      <name>vlion</name>
    </author>
    <dw:poster user="vlion"/>
    <link rel="alternate" type="text/html" href="https://dw-dev.dreamwidth.org/133161.html"/>
    <link rel="self" type="text/xml" href="https://dw-dev.dreamwidth.org/data/atom/?itemid=133161"/>
    <title>posterous-&amp;gt;dw migration script</title>
    <published>2013-02-24T09:48:03Z</published>
    <updated>2013-02-24T09:48:03Z</updated>
    <category term="scripts"/>
    <dw:security>public</dw:security>
    <dw:reply-count>0</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='vlion' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://vlion.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://vlion.dreamwidth.org/'&gt;&lt;b&gt;vlion&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Hi,&lt;br /&gt;&lt;br /&gt;I have a Posterous-&amp;gt;dw migration script.  It kind of works. It worked for me taking my Posterous backup and putting it on a Dreamwidth install foxfirefey has going.&lt;br /&gt;&lt;br /&gt;However, it is a funky stanky horrid mash of Python and Ruby. It code smells like old socks.&lt;br /&gt;&lt;br /&gt;It does:&lt;br /&gt;&lt;br /&gt;- give you dates&lt;br /&gt;&lt;br /&gt;- Give you titles.&lt;br /&gt;&lt;br /&gt;- Give you actual post.&lt;br /&gt;&lt;br /&gt;It does not&lt;br /&gt;&lt;br /&gt;- Do formatting.&lt;br /&gt;&lt;br /&gt;- Do images.&lt;br /&gt;&lt;br /&gt;- Do easy. It requires a few rubygems[1].&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;&lt;br /&gt;So. Is this going to be useful? Helpful? I can stuff it up on a github and maybe someone can take this and turn it into mo' usable code. What needs to happen - IMO- for mo' happiness is:&lt;br /&gt;&lt;br /&gt;- Username/password not on the CLI, instead, an interactive dialog&lt;br /&gt;&lt;br /&gt;- Ruby removed and replaced with Python such that the Python default install works.&lt;br /&gt;&lt;br /&gt;- Formatting handled appropriately. Python Etree explodes on posterous html; HTMLParser is underpowered and will require gyrations to do this right.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Let me know what people want, if this is something wanted, I'll upload it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;[1]. If you're not a developer on Linux/OSX, this is going to be (a) gibberishy and (b) impossible to deal with in any sort of way that doesn't involve grief.&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=dw_dev&amp;ditemid=133161" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-04-22:10:124731</id>
    <author>
      <email>mark@plogs.net</email>
      <name>Mark Smith</name>
    </author>
    <dw:poster user="mark"/>
    <link rel="alternate" type="text/html" href="https://dw-dev.dreamwidth.org/124731.html"/>
    <link rel="self" type="text/xml" href="https://dw-dev.dreamwidth.org/data/atom/?itemid=124731"/>
    <title>Important: Update to "dwu"</title>
    <published>2012-09-23T21:16:36Z</published>
    <updated>2012-09-23T21:16:36Z</updated>
    <category term="scripts"/>
    <category term="github"/>
    <dw:security>public</dw:security>
    <dw:reply-count>3</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='mark' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://mark.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user_staff.png' alt='[staff profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://mark.dreamwidth.org/'&gt;&lt;b&gt;mark&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you use the "dwu" script from the wiki, you will need to update your local copy. I've made some changes because the last version of the script would merge changes from both develop and master, leading to broken environments and GitHub repositories.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://wiki.dwscoalition.org/wiki/index.php/Dev_Maintenance#dwu_-_Updating_the_repos"&gt;http://wiki.dwscoalition.org/wiki/index.php/Dev_Maintenance#dwu_-_Updating_the_repos&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Please use the updated script.&lt;br /&gt;&lt;br /&gt;If you have gotten yourself into a broken state, let me know and I can walk you through fixing it. There is some force pushing involved, sadly.&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=dw_dev&amp;ditemid=124731" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-04-22:10:113891</id>
    <author>
      <name>Cocoa</name>
    </author>
    <dw:poster user="momijizukamori"/>
    <link rel="alternate" type="text/html" href="https://dw-dev.dreamwidth.org/113891.html"/>
    <link rel="self" type="text/xml" href="https://dw-dev.dreamwidth.org/data/atom/?itemid=113891"/>
    <title>Some tools for S2 patching</title>
    <published>2012-04-19T06:05:37Z</published>
    <updated>2012-04-19T06:39:01Z</updated>
    <category term="scripts"/>
    <category term="styles"/>
    <dw:security>public</dw:security>
    <dw:reply-count>4</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='momijizukamori' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://momijizukamori.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://momijizukamori.dreamwidth.org/'&gt;&lt;b&gt;momijizukamori&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;...mostly because as anyone who gets all the bugzilla and/or style notifs knows, I did a lot of that this week *g*&lt;br /&gt;&lt;br /&gt;First, preview images - I'd been doing them with Ubuntu's screenshot utility and photoshop, which is 1) really slow and 2) doesn't really adequately strip and compress images. So! Enter &lt;a href="https://chrome.google.com/webstore/detail/cpngackimfmofbokmjmljamhdncknpmg"&gt;Screen Capture&lt;/a&gt; for Google Chrome, which I've been using with the 'full page' setting, and set to skip pop-ups and save straight to a temp image directory, where I can then rename the screenshots. After that, &lt;span style='white-space: nowrap;'&gt;&lt;a href='https://geekosaur.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://geekosaur.dreamwidth.org/'&gt;&lt;b&gt;geekosaur&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; and &lt;span style='white-space: nowrap;'&gt;&lt;a href='https://exor674.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://exor674.dreamwidth.org/'&gt;&lt;b&gt;exor674&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; (with a little sideline ImageMagick input from &lt;span style='white-space: nowrap;'&gt;&lt;a href='https://www.dreamwidth.org/profile?user=tamouse_'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://www.dreamwidth.org/profile?user=tamouse_'&gt;&lt;b&gt;tamouse_&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; helped me write this handy little shell script, to process all the pngs in the directory you run them on - it resizes them, crops them, strips color profiles, and indexes them.&lt;br /&gt;&lt;br /&gt;&lt;textarea cols="50" rows="10"&gt;#!/bin/bash
for f in *.png; do
    convert -resize 150x114^ -gravity north -extent 150x114 -sharpen 25 +dither -type Palette "$f" png8:"out.png" &amp;&amp;
        pngnq -n 256 -s 1 -f out.png &amp;&amp;
        pngcrush -c 3 -bit_depth 8 -rem alla -brute out-nq8.png "$f" &amp;gt;/dev/null &amp;&amp;
        rm out.png out-nq8.png
done
&lt;/textarea&gt;&lt;br /&gt;&lt;br /&gt;I've been using it on my own machine, as I run Ubuntu, but I believe all the appropriate packages are now on the Dreamhack server, too, for server-side use.&lt;br /&gt;&lt;br /&gt;Second, &lt;span style='white-space: nowrap;'&gt;&lt;a href='https://rb.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://rb.dreamwidth.org/'&gt;&lt;b&gt;rb&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; posted &lt;a href="http://dw-dev.dreamwidth.org/106347.html"&gt;a handy little script for sorting properties for color themes and generating appropriate headers&lt;/a&gt;. I updated it to match our current formatting for files, add sorting for a few more properties, and output more verbose instructions on what to do next at the end.&lt;br /&gt;&lt;br /&gt;&lt;textarea cols="50" rows="10"&gt;
#!/usr/bin/perl
#
#

my ( $theme_human, $author_name, $layout_human, $is_nonfree ) = @ARGV;

sub diehelp {
    warn "Syntax: newtheme ThemeName AuthorName LayoutName IsNonfree";
    exit;
}

if ( !$theme_human ) {
    warn "No theme name provided.";
    diehelp;
}
if ( !$layout_human ) {
    warn "No layout name provided.";
    diehelp;
}

( $layout_name = lc ( $layout_human ) ) =~ s/\s//g;
( $theme_name = lc ( $theme_human ) ) =~ s/\s//g;


my ( @dropped, @css, @set, $in_css );
while ( &amp;lt;STDIN&amp;gt; ) {
    my $line = $_;

    if ( $in_css ) {
        if ( $line =~ m/"""; }/ ) {
            $in_css = 0;
            next;
        }
        push( @css, $line );
    } elsif ( $line =~ m/function Page::print_theme_stylesheet/ ) {
        $in_css = 1;
    } elsif ( /^\.$/ ) {
        break;
    } else {
        next unless $line;
        if ( $line =~ m/^layerinfo / ) {
            push( @dropped, $line );
            next;
        }

        push( @set, $line );
    }
}

# process @set lines
my ( @unknown, @presentation, @page, @entries, @modules, @fonts, @images );
foreach ( @set ) {
    if ( /userlite_interaction_links = / || /_management_links = / || /module.*order/ || /module.*show/ ) {
        push( @dropped, $_ );
    } elsif ( /font/ ) {
        push( @fonts, $_ );
    } elsif ( /module/ ) {
        push( @modules, $_ );
    } elsif ( /entry/ ) {
        push( @entries, $_ );
    } elsif ( /comment/ ) {
        push( @entries, $_ );
    } elsif ( /links/ || /layout/ ) {
        push( @presentation, $_ );
    } elsif ( /color/ ) {
        push( @page, $_ );
    } elsif ( /image/ ) {
        push( @images, $_ );
    } else {
        push( @unknown, $_ );
    }
}

my $filename = "$ENV{LJHOME}/temp/$layout_name-$theme_name.s2";
open TMP_FILE, "&amp;gt; $filename";

print TMP_FILE &amp;lt;&amp;lt;"EOT";
#NEWLAYER: $layout_name/$theme_name
layerinfo type = "theme";
layerinfo name = "$theme_human";
layerinfo redist_uniq = "$layout_name/$theme_name";
layerinfo author_name = "$author_name";

set layout_authors = [ { "name" =&amp;gt; "$author_name", "type" =&amp;gt; "user" } ];
EOT

# print @set lines
sub print_section {
    my ( $name, @lines ) = @_;

    if (@lines) {
        print TMP_FILE&amp;lt;&amp;lt;"EOT";

##===============================
## $name
##===============================

EOT
        foreach ( @lines ) {
            print TMP_FILE $_;
        }
    }
}

print_section( "Presentation", @presentation );
print_section( "Page", @page );
print_section( "Entry", @entries );
print_section( "Module", @module );
print_section( "Fonts", @fonts );
print_section( "Images", @images );
if ( @css ) {
    print TMP_FILE "\n";
    print TMP_FILE 'function Page::print_theme_stylesheet() { """' . "\n";
    foreach ( @css ) {
        print TMP_FILE "    " . $_;
    }
    print TMP_FILE '"""; }' . "\n";
}
print_section( "Unknown - DELETE THIS SECTION after reclassifying lines", @unknown );
print_section( "Dropped - DELETE THIS SECTION after verifying none of it is needed", @dropped );
print TMP_FILE "\n";
close TMP_FILE;

print "Parsed theme now saved in file: $filename\n";
print "Be sure to check this for hardcoded font sizes and color codes that can be shortened.\n";
print "This new text needs to be put into the existing file named:\n";
print "$ENV{LJHOME}/bin/upgrading/s2layers/$layout_name/theme.s2\n\n";
if ( @images ) {
    print "This layout appears to have image(s). Change their url to $layout_name/$theme_name(_imagename, if multiple), rename the image to $theme_name(_imagename), and put in:\n";
    print "$ENV{LJHOME}/htdocs/stc/$layout_name/$theme_name.png\n\n";
    }
print "Theme also needs a preview screenshot. Resize to 150x114px and put in:\n";
print "$ENV{LJHOME}/htdocs/img/customize/previews/$layout_name/$theme_name.png\n\n";
print "(for additional reference on cleaning themes, see http://wiki.dwscoalition.org/notes/Newbie_Guide_for_People_Patching_Styles#Adding_a_New_Color_Theme )";
&lt;/textarea&gt;&lt;br /&gt;&lt;br /&gt;This is written to be used server-side right now, with a command-line input like './newtheme.pl "Human-Readable Theme Name" user "Layout This Theme Is For" yes &amp;lt; inputfile' I've been running it client-side by changing line 74, 'my $filename = "$ENV{LJHOME}/temp/$layout_name-$theme_name.s2";' to 'my $filename = "temp_themes/$layout_name-$theme_name.s2";' (otherwise it tries to write to root, and That's Bad. And unnecessary)&lt;br /&gt;&lt;br /&gt;Third, for the tiny handful of people doing S2 work on gedit (shhh, I like it, okay), I made some &lt;a href="http://pastebin.com/MVdY2XRb"&gt;mods to the CSS syntax highlighting file (pastebin because the file is big)&lt;/a&gt;. I tried to get it to make a custom S2 language, but it was being fussy about parsing it, and a lot of the .s2 files are largely CSS anyway. So this adds highlighting for S2 variables and S2 keywords! It goes in a file called CSS.lang in home/.local/usr/share/gtksourceview-2.0/language-specs, which will probably not exist if you haven't made custom languages. If you're on newer versions that use GTK3, that 2.0 should be a 3.0. You may have to manually select the highlighting, for some reason it only registers the .s2 extension some of the time.&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=dw_dev&amp;ditemid=113891" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-04-22:10:106347</id>
    <author>
      <name>Ricky Buchanan</name>
    </author>
    <dw:poster user="jeshyr"/>
    <link rel="alternate" type="text/html" href="https://dw-dev.dreamwidth.org/106347.html"/>
    <link rel="self" type="text/xml" href="https://dw-dev.dreamwidth.org/data/atom/?itemid=106347"/>
    <title>S2 Patch Assist Script</title>
    <published>2012-01-07T10:27:12Z</published>
    <updated>2012-01-07T10:29:50Z</updated>
    <category term="styles"/>
    <category term="scripts"/>
    <dw:security>public</dw:security>
    <dw:reply-count>1</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='jeshyr' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://jeshyr.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://jeshyr.dreamwidth.org/'&gt;&lt;b&gt;jeshyr&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Right before my brain got refried by this stupid disease I was working on a script to turn the theme layers copied from DW  itself into the right format to paste into the s2 code in the sourcecode. I was doing it as I learned how so it's only been tested on about 5 different situations at the moment and I'm quite sure it doesn't do everything so check all output please!!&lt;br /&gt;&lt;br /&gt;And yes, my brain got fried (again) by this stupid disability so I'm on indefinite leave from developing for the mean time - and VERY disappointed about it.&lt;br /&gt;&lt;br /&gt;At the moment you want to pipe the theme layer through STDIN to the script, so something like&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ ./newtheme.pl NewThemeName Rising "Tabula Rasa" yes &amp;lt; ~/file-with-theme-layer.txt&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;it will tell you what file it writes the output to, it will be something in $LJHOME/temp/&lt;br /&gt;&lt;br /&gt;Script&lt;br /&gt;&lt;br /&gt;&lt;textarea rows="15" cols="80"&gt;#!/usr/bin/perl
#
#

my ( $theme_human, $author_name, $layout_human, $is_nonfree ) = @ARGV;

sub diehelp {
    warn "Syntax: newtheme ThemeName AuthorName LayoutName IsNonfree";
    exit;
}

if ( !$theme_human ) {
    warn "No theme name provided.";
    diehelp;
}
if ( !$layout_human ) {
    warn "No layout name provided.";
    diehelp;
}

( $layout_name = lc ( $layout_human ) ) =~ s/\s//g;
( $theme_name = lc ( $theme_human ) ) =~ s/\s//g;


my ( @dropped, @css, @set, $in_css );
while ( &amp;lt;STDIN&amp;gt; ) {
    my $line = $_;

    if ( $in_css ) {
        if ( $line =~ m/"""; }/ ) {
            $in_css = 0;
            next;
        }
        push( @css, $line );
    } elsif ( $line =~ m/function Page::print_theme_stylesheet/ ) {
        $in_css = 1;
    } elsif ( /^\.$/ ) {
        break;
    } else {
        next unless $line;
        if ( $line =~ m/^layerinfo / ) {
            push( @dropped, $line );
            next;
        }

        push( @set, $line );
    }
}

# process @set lines
my ( @unknown, @presentation, @page, @entries, @modules, @fonts );
foreach ( @set ) {
    if ( /userlite_interaction_links = / || /_management_links = / || /module.*order/ || /module.*show/ ) {
        push( @dropped, $_ ); 
    } elsif ( /font/ ) {
        push( @fonts, $_ );
    } elsif ( /module/ ) {
        push( @modules, $_ );
    } elsif ( /entry/ ) {
        push( @entries, $_ );
    } elsif ( /comment/ ) {
        push( @entries, $_ );
    } elsif ( /links/ ) {
        push( @presentation, $_ );
    } elsif ( /color/ ) {
        push( @page, $_ );
    } else {
        push( @unknown );
    }
}

my $filename = "$ENV{LJHOME}/temp/$layout_name-$theme_name.s2";
open TMP_FILE, "&amp;gt; $filename";

print TMP_FILE &amp;lt;&amp;lt;"EOT";
#NEWLAYER: $layout_name/$theme_name
layerinfo "type" = "theme";
layerinfo "name" = "$theme_human";
layerinfo "redist_uniq" = "$layout_name/$theme_name";
layerinfo "author_name" = "$author_name";

set layout_authors = [ { "name" =&amp;gt; "$author_name", "type" =&amp;gt; "user" } ];
EOT

# print @set lines
sub print_section {
    my ( $name, @lines ) = @_;

    if (@lines) {
        print TMP_FILE&amp;lt;&amp;lt;"EOT";

##===============================
## $name
##===============================
EOT
        foreach ( @lines ) {
            print TMP_FILE $_;
        }
    }
}

print_section( "Presentation", @presentation );
print_section( "Page", @page );
print_section( "Entry", @entries );
print_section( "Module", @module );
print_section( "Fonts", @fonts );
if ( @css ) {
    print TMP_FILE "\n";
    print TMP_FILE 'function Page::print_theme_stylesheet() { """' . "\n";
    foreach ( @css ) {
        print TMP_FILE "    " . $_;
    }
    print TMP_FILE '"""; }' . "\n";
}
print_section( "Unknown - DELETE THIS SECTION after reclassifying lines", @unknown );
print_section( "Dropped - DELETE THIS SECTION after verifying none of it is needed", @dropped );
print TMP_FILE "\n";
close TMP_FILE;

print "Parsed theme now saved in file: $filename\n";
print "This new text needs to be put into the existing file named:\n";
print "$ENV{LJHOME}/bin/upgrading/s2layers/$theme_name/theme.s2\n\n";
print "Theme also needs a preview screenshot. Resize to 150x114px and put in:\n";
print "$ENV{LJHOME}/htdocs/img/customize/previews/$theme_name/$layout_name.png\n\n";
&lt;/textarea&gt;&lt;br /&gt;&lt;br /&gt;Feedback, cases that break it, improvements, etc. would all be great.&lt;br /&gt;&lt;br /&gt;r&lt;br /&gt;&lt;br /&gt;Edit: Now with super bonus functioning HTML tags!&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=dw_dev&amp;ditemid=106347" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-04-22:10:96890</id>
    <author>
      <name>fu</name>
    </author>
    <dw:poster user="fu"/>
    <link rel="alternate" type="text/html" href="https://dw-dev.dreamwidth.org/96890.html"/>
    <link rel="self" type="text/xml" href="https://dw-dev.dreamwidth.org/data/atom/?itemid=96890"/>
    <title>lookup-routing: tool to help navigate the routing system</title>
    <published>2011-09-23T10:04:25Z</published>
    <updated>2011-09-23T16:25:19Z</updated>
    <category term="scripts"/>
    <dw:security>public</dw:security>
    <dw:reply-count>3</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='fu' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://fu.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://fu.dreamwidth.org/'&gt;&lt;b&gt;fu&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='white-space: nowrap;'&gt;&lt;a href='https://exor674.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://exor674.dreamwidth.org/'&gt;&lt;b&gt;exor674&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; has added another tool to the &lt;a href="http://wiki.dwscoalition.org/notes/Dev_Tools"&gt;dev tools repository&lt;/a&gt;, called &lt;a href="http://wiki.dwscoalition.org/notes/Dev_Tools/lookup-routing"&gt;lookup-routing&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It does several things.&lt;br /&gt;&lt;br /&gt;First, you can easily find out which file handles what page (e.g., /nav, /nav/create, /rename, /admin, /post, etc). &lt;br /&gt;&lt;br /&gt;&lt;tt&gt;$ lookup-routing /admin&lt;br /&gt;app: /admin is a redirect to /admin/&lt;br /&gt;app: /admin/ is defined in the file cgi-bin/DW/Controller/Admin.pm, and using the handler sub admin_handler&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;This is useful if you're working on a bug that's been reported on /some/path/here, and you want to know which file to open up first.&lt;br /&gt;&lt;br /&gt;(Psst If "lookup-routing /some/path" doesn't work, it is probably a BML file. Try htdocs/some/path.bml)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="cut-wrapper"&gt;&lt;span style="display: none;" id="span-cuttag___1" class="cuttag"&gt;&lt;/span&gt;&lt;b class="cut-open"&gt;(&amp;nbsp;&lt;/b&gt;&lt;b class="cut-text"&gt;&lt;a href="https://dw-dev.dreamwidth.org/96890.html#cutid1"&gt;--verbose gives you a much more detailed view (plus some debugging tips)&lt;/a&gt;&lt;/b&gt;&lt;b class="cut-close"&gt;&amp;nbsp;)&lt;/b&gt;&lt;/span&gt;&lt;div style="display: none;" id="div-cuttag___1" aria-live="assertive"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Second, you can get a list of everything in the routing table, using the --list argument:&lt;br /&gt;&lt;tt&gt;$ lookup-routing --list&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;You can filter the list down to either those that use regex matching, or those that use string-matching:&lt;br /&gt;&lt;tt&gt;$ lookup-routing --list --regex&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;$ lookup-routing --list --string&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You can also filter down to just those pages in user-space, app-space, or ssl using --role=user, --role=app, --role=ssl, respectively. Default is --role=all.&lt;br /&gt;&lt;br /&gt;There are --user, --app, --ssl shortcuts which do the same as their --role=... equivalents.&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;$ lookup-routing --list --user&lt;/tt&gt; # lists paths handled by the routing system that follow the form &lt;a href="http://exampleusername.dreamwidth.org/some/path/here"&gt;http://exampleusername.dreamwidth.org/some/path/here&lt;/a&gt;&lt;br /&gt;&lt;tt&gt;$ lookup-routing --list --app&lt;/tt&gt; # lists paths handled by the routing system that follow the form &lt;a href="http://www.dreamwidth.org/some/path/here"&gt;http://www.dreamwidth.org/some/path/here&lt;/a&gt;&lt;br /&gt;&lt;tt&gt;$ lookup-routing --list --ssl&lt;/tt&gt; # lists paths routing system that use https&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And third, you can get a quick summary of stats by running&lt;br /&gt;&lt;tt&gt;lookup-routing --stats&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;A quick reminder of which arguments to use is available by running:&lt;br /&gt;&lt;tt&gt;lookup-routing --help&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;Very detailed usage instructions can be found by running:&lt;br /&gt;&lt;tt&gt;lookup-routing --help --verbose&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you haven't already installed the dev tools yet, see &lt;a href="http://wiki.dwscoalition.org/notes/Dev_Tools"&gt;the Dev Tools wiki page&lt;/a&gt;. If you've installed the dev tools before, make sure to update your code, to pull in the changes.&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=dw_dev&amp;ditemid=96890" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-04-22:10:96005</id>
    <author>
      <name>Sophie</name>
    </author>
    <dw:poster user="sophie"/>
    <link rel="alternate" type="text/html" href="https://dw-dev.dreamwidth.org/96005.html"/>
    <link rel="self" type="text/xml" href="https://dw-dev.dreamwidth.org/data/atom/?itemid=96005"/>
    <title>Mass user-creation script</title>
    <published>2011-09-02T20:44:13Z</published>
    <updated>2011-09-02T20:54:11Z</updated>
    <category term="reviewing"/>
    <category term="testing"/>
    <category term="scripts"/>
    <dw:security>public</dw:security>
    <dw:reply-count>9</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='sophie' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://sophie.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://sophie.dreamwidth.org/'&gt;&lt;b&gt;sophie&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I've just put a &lt;a href="http://wiki.dwscoalition.org/notes/Script:_create-users"&gt;mass user-creation script&lt;/a&gt; on the wiki. It allows you to create any number of users and have them be auto-validated. It will also randomly create watch/trust edges between the created users, and if you specify it, they will all join any given community. This makes it extremely useful when you have a bug that requires a large number of users to test, such as &lt;a href="http://bugs.dwscoalition.org/show_bug.cgi?id=2215"&gt;bug 2215: member list page: "jump to account" does not jump to username&lt;/a&gt;, which requires more than 100 users in a single community.&lt;br /&gt;&lt;br /&gt;(I actually already had this script created some time ago, but hadn't released it publicly. However, when I saw &lt;span style='white-space: nowrap;'&gt;&lt;a href='https://kjwcode.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://kjwcode.dreamwidth.org/'&gt;&lt;b&gt;kjwcode&lt;/b&gt;&lt;/a&gt;&lt;/span&gt; manually creating 100 users in order to test the patch on the aforementioned bug, I added the community-joining ability and offered the script to him, and realised I should probably release it for all to use!)&lt;br /&gt;&lt;br /&gt;There are a few things the script doesn't do yet. For example, while it can make all the users join a community, it won't make any of them subscribe to it. If anybody wants more features added, let me know!&lt;br /&gt;&lt;br /&gt;And, in the interests of code preservation (in case the wiki ever disappears for some reason - not that it should), I'm reproducing the code as it is now inside a cut. Bear in mind that it's possible that the version on the wiki may be more up-to-date if it's been some time since this post was made, so you should probably &lt;a href="http://wiki.dwscoalition.org/notes/Script:_create-users"&gt;check on the wiki first&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;&lt;span class="cut-wrapper"&gt;&lt;span style="display: none;" id="span-cuttag___1" class="cuttag"&gt;&lt;/span&gt;&lt;b class="cut-open"&gt;(&amp;nbsp;&lt;/b&gt;&lt;b class="cut-text"&gt;&lt;a href="https://dw-dev.dreamwidth.org/96005.html#cutid1"&gt;Source code follows!&lt;/a&gt;&lt;/b&gt;&lt;b class="cut-close"&gt;&amp;nbsp;)&lt;/b&gt;&lt;/span&gt;&lt;div style="display: none;" id="div-cuttag___1" aria-live="assertive"&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=dw_dev&amp;ditemid=96005" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-04-22:10:94822</id>
    <author>
      <name>Ricky Buchanan</name>
    </author>
    <dw:poster user="jeshyr"/>
    <link rel="alternate" type="text/html" href="https://dw-dev.dreamwidth.org/94822.html"/>
    <link rel="self" type="text/xml" href="https://dw-dev.dreamwidth.org/data/atom/?itemid=94822"/>
    <title>Potentially Useful Do-Everything Script</title>
    <published>2011-08-21T13:16:32Z</published>
    <updated>2013-04-22T03:44:10Z</updated>
    <category term="scripts"/>
    <dw:security>public</dw:security>
    <dw:reply-count>11</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='jeshyr' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://jeshyr.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://jeshyr.dreamwidth.org/'&gt;&lt;b&gt;jeshyr&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;[BTW: I am editing this post as the script is updated so refer back for further edits.]&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;I'm just a newbie at developing - submitted my first patch today - and one of the things one has to do to get up and running is to read about 5 tons of documentation and figure out workflows. Since I was having lots of potentially useful scripts suggested to me by developers and by the wiki and since I am at heart a toolmaker I put them all together and documented everything to the best of my ability.&lt;br /&gt;&lt;br /&gt;I think this works but it's way past my bedtime right now and I haven't tested every single combination so if it eats your code, your data, or your firstborn child be in on your own head. OTOH I think it should work right!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;textarea rows="15" cols="80"&gt;
#!/bin/bash
#
# Ricky's Dreamwidth Do-Anything Script
# For current version see: http://dw-dev.dreamwidth.org/94822.html
#
# Last updated 22 April 2013
#

#
# CHANGES
# 22/4/13 - Extended 'git' help page
# 20/4/13 - Fix 'upgrade' command again. Oops. I think it works now?
#         - Added 'hardreset' command with tons of warnings
#         - Added 'upgradebranch' command and help info
#         - Added/updated various help texts
#         - Abstract out $SCRIPTNAME variable
#         - Added 'git' command
#         - Added abstract stuff for storing/restoring current git branch
# 25/9/12 - Update 'upgrade' command following xb95's post http://dw-dev.dreamwidth.org/124731.html
# 10/9/12 - Update everything for git - deleted unpatch, makepatch, sync commands. Updated tidy, upgrade, help commands.
#         - Add 'checkconfig' option
#         - Now restores initial directory before exitting
#         - Added 'free' and 'nonfree' commands to save Afuna's poor fingers a few keystrokes
# 28/10/11 - Unpatch now really does cope with specific directory names (I should abstract out the interpolation code)
# 22/10/11 - Unpatch now copes with specific directory names
#         - Tidy really totally works
#         - Upgrade no longer starts apache
# 13/9/11 - Fixed 'tidy' command so it actually works!
# 11/9/11 - Added 'unpatch', 'errlog' and 'errlogs' commands.
#           'makepatch' command now accepts filename on command line.
# 2/9/11  - Added 'up' and 'down' commands.
#           Removed check before restarting Apache, seems excessive.
# 29/8/11 - Upgrade now deletes files not present in repository
#           Clarified warning text displayed before upgrading.
#

# When verbose is set extra 'help' text is printed.
verbose="1"

# Name to use for any patch which is not given a specific name
default_patchname="~/default.patch"

inquire ()  {
    # Usage: inquire "Prompt string" [force]
    # use 'force' keyword to force an answer, otherwise answer defaults to Yes if user presses enter

    if [ "$2" = 'force' ]; # must explicitly type the answer
    then
        force=YES
        echo  -n "$1 [y/n]? "
    else
        force=NO
        echo  -n "$1 [Y/n]? "
    fi

    read answer
    #echo "Force is $force";
    
    finish="-1"
    while [ "$finish" == '-1' ]; do
        if [[ "$force" == 'NO' &amp;&amp; "$answer" == '' ]];
        then
	    #echo "Defaulting to 'yes'."
            finish="1"; # Empty answer OK because force is off
        else
	    #echo "Not defaulting..."
            case $answer in
                y | Y | yes | YES | Yes ) 
		    finish="1";;
                n | N | no | NO | No ) 
		    echo 'Exiting.';
		    exit;;
                *) 
                   finish="-1";
                   echo -n 'Invalid response - please reenter: ';
                   read answer;;
             esac
        fi
    done
}

update-db () {
    echo "Now updating databases ..."
    $LJHOME/bin/upgrading/update-db.pl -r -p --innodb &amp;&amp; \
    $LJHOME/bin/upgrading/update-db.pl -r --cluster=all --innodb &amp;&amp; \
    $LJHOME/bin/upgrading/texttool.pl load
}



# TODO put stop-apache and start-apache commands in here as functions

SCRIPTNAME=`basename $0`

# Save initial directory for possible restoration later
OLDDIR=$PWD
NODIRRESTORE=0 # Change to 1 for no directory restoration ever

# Save initial git branch for possible restoration later
OLDBRANCH=`git rev-parse --symbolic-full-name --abbrev-ref HEAD`
NOBRANCHRESTORE=0 # Change to 1 for no branch restoration ever
if [ $OLDBRANCH == "HEAD" ]; then
    # Detached head state - no restoring possible
    NOBRANCHRESTORE=1
fi

CMD=$1
case $CMD in

up)
    # Start Apache
    echo "Starting Apache..."
    start-apache
    if [ $verbose == 1 ]; then 
        echo "Remember to stop Apache with the '$SCRIPTNAME down' command when you're finished hacking."
        echo "Leaving Apache running slows down the server a touch for everybody else."
    fi
    ;;

down)
    # Stop Apache
    echo "Stopping Apache and any instances of worker-manager..."
    stop-apache
    killall worker-manager
    ;;

restart|r|bounce|b|bap)
    # Restart Apache
    #inquire "Do you wish to restart apache?"
    
    echo "Restarting Apache ..."
    stop-apache
    sleep 3
    start-apache
    if [ $verbose == 1 ]; then 
        echo "Remember to stop Apache with the '$SCRIPTNAME down' command when you're finished hacking."
        echo "Leaving Apache running slows down the server a touch for everybody else."
    fi
    ;;

upgrade)
    # Upgrade code from repositories and rebuild DBs
    echo "WARNING: Upgrading your dreamhack may delete local code changes."
    if [ $verbose == 1 ]; then 
        echo "To save any uncommitted code changes, you can commit them or use the 'git stash' command. Use 'git stash help' for details."
    fi

    inquire "Do you wish to upgrade your Dreamhack code" force

    cd $LJHOME
    git fetch dreamwidth
    # pull changes from dreamwidth
    git checkout develop
    git pull --ff dreamwidth develop
    git checkout master
    git pull --ff dreamwidth master
    # push them to Github forks
    git push origin develop
    git push origin master
    # change to dw-nonfree
    cd $LJHOME/ext/dw-nonfree
    git fetch dreamwidth
    # pull changes from dw-nonfree
    git checkout develop
    git pull --ff dreamwidth develop
    git checkout master
    git pull --ff dreamwidth master
    # push them to Github forks
    git push origin develop
    git push origin master

    update-db

    if [ $NOBRANCHRESTORE == 0 ]; then 
        echo "Switching back to git branch $OLDBRANCH"
        git checkout $OLDBRANCH
    else
        echo "You are now in git branch $NEWBRANCH"
    fi

    echo "You may now wish to run '$SCRIPTNAME upgradebranch' to pull changes into your current branch."
    ;;


upgradebranch|ub)
    if [ $verbose == 1 ]; then 
        echo "This command pulls the latest changes you have downloaded from the develop branch into whatever branch you are currently working, and should be run after '$SCRIPTNAME upgrade'."
        echo "To save any uncommitted code changes, you can commit them or use the 'git stash' command. Use 'git stash help' for details."
    else
        echo "This command pulls already-downloaded changes from develop into your current git branch and should be run after '$SCRIPTNAME upgrade' or equivalent."
    fi
 
    inquire "Do you wish to pull upgraded code into your current branch"

    git pull --rebase --ff-only dreamwidth develop
    ;;

hardreset)
    # Upgrade code from repositories and rebuild DBs
    echo "WARNING: Hard resetting your Dreamhack WILL delete anything in $LJHOME which is comitted, checked in, or staged but not part of the official Dreamhost code. "
    echo "    Changes which are stashed will be preserved though."
    if [ $verbose == 1 ]; then 
        echo "    If you feel unsure about this, we suggest you ask somebody on the dreamwidth-dev community for help - we're happy to help you."
    fi
    inquire "Do you wish to HARD RESET your Dreamhack code" force

    cd $LJHOME
    git checkout develop
    git fetch dreamwidth
    git reset --hard dreamwidth/master
    git reset --hard dreamwidth/develop

    update-db
    ;;

checkconfig|ccfg)
    # Check Configuration
    cd $LJHOME
    bin/checkconfig.pl
    ;;

free)
    cd $LJHOME
    NODIRRESTORE=1
    ;;

nonfree|nf)
    cd $LJHOME/ext/dw-nonfree
    NODIRRESTORE=1
    ;;

update|db)
    # Database update commands
    # When: After editing styles (s2) or made changes to DB schema, run this to make changes live
    inquire "Do you wish to update the database"

    update-db
    ;;

tidy)
    # Deletes stray git artififacts
    git clean -f "*.rej" "*.orig"
    ;;

errlog)
    tail ~/apache/logs/error_log
    ;;

errlogs)
    tail -f ~/apache/logs/error_log
    ;;

git|cheatsheet)
   echo "git branch             Show all branches, current branch is asterisked"
   echo "git checkout BRANCH    Switch to branch BRANCH"
   echo "git checkout -b BRANCH Create and switch to new branch BRANCH"
   echo "git status -s          Show files added/removed/modified not committed"
   echo "git diff               Show current unstaged changes"
   echo "git diff --cached      Show current uncommitted changes"
   echo "git stash [pop|show]   Store/restore/show stored uncommitted changes"
   echo ""

   echo "More details here: http://wiki.dwscoalition.org/wiki/index.php/Newbie_Guide:_How_To_in_Git"
    ;;

*)
    # Invalid or missing command - prompt again
    echo "Valid commands are:"
    echo "    restart, r, bounce, b"
    echo "        Stops and then immediately restarts Apache. Use after editing .pm files or updating database."
    echo "    up, down"
    echo "        Starts or stops Apache."
    echo "    free, nonfree"
    echo "        Move to the free/nonfree directories."
    echo "    upgrade"
    echo "        Pull all new changes from github."
    echo "    upgradebranch, ub"
    echo "        Grab the changes from the most recent upgrade into your current branch."
    echo "    hardreset"
    echo "        Delete all your local changes and reset your dreamhack's status to match the current development code."
    echo "    update, db"
    echo "        Update databases. Use after editing database schema or S2 code."
    echo "    tidy"
    echo "        Delete stray patching artifiact files in current directory."
    echo "    errlog[s]"
    echo "        Tail [-f] the Apache error logs."
    echo "    git Display git cheat-sheet."

esac

if [ $NODIRRESTORE == 0 ]; then 
    cd $OLDDIR
fi
echo "DW script exiting."
&lt;/textarea&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For new folks, you need to copy everything in the text box above and paste it into a new file on your Dreamhack. I suggest you put it in the ~/bin directory and call the file 'dw', because then your system matches mine :). Then you need to make that file executable by typing 'chmod +755 ~/bin/dw' or whatever filename you used. After that you can type 'dw' and it should execute just fine, it'll give you instructions.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I would welcome fixes, constructive criticism, or anything else you have to offer. Feel free to use this in any way you want, etc.&lt;br /&gt;&lt;br /&gt;r&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=dw_dev&amp;ditemid=94822" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
  <entry>
    <id>tag:dreamwidth.org,2008-04-22:10:69778</id>
    <author>
      <name>pseudomonas</name>
    </author>
    <dw:poster user="pseudomonas"/>
    <link rel="alternate" type="text/html" href="https://dw-dev.dreamwidth.org/69778.html"/>
    <link rel="self" type="text/xml" href="https://dw-dev.dreamwidth.org/data/atom/?itemid=69778"/>
    <title>DW Perl module client</title>
    <published>2010-09-09T14:29:38Z</published>
    <updated>2010-09-16T17:47:16Z</updated>
    <category term="scripts"/>
    <dw:security>public</dw:security>
    <dw:reply-count>11</dw:reply-count>
    <content type="html">Posted by: &lt;span lj:user='pseudomonas' style='white-space: nowrap;' class='ljuser'&gt;&lt;a href='https://pseudomonas.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/user.png' alt='[personal profile] ' width='17' height='17' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://pseudomonas.dreamwidth.org/'&gt;&lt;b&gt;pseudomonas&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Does LJ::Simple work reliably with Dreamwidth? If not, is there a comparable perl module that does? (I'd rather rely on someone else's testing than conduct my own, which is likely to be more slipshod)&lt;br /&gt;&lt;br /&gt;Also (and relatedly), is there a way that given a DW entry that's been either imported from, or crossposted to, LJ, I can get (programmatically) the ID or URL of the LJ entry, without resorting to comparing timestamps and post contents?&lt;br /&gt;&lt;br /&gt;&lt;i&gt;ETA: if there's no Perl thing suitable, does anyone have any ideas for Java packages that would do the same?&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;(x-posted from &lt;span style='white-space: nowrap;'&gt;&lt;a href='https://perl.dreamwidth.org/profile'&gt;&lt;img src='https://www.dreamwidth.org/img/silk/identity/community.png' alt='[community profile] ' width='16' height='16' style='vertical-align: text-bottom; border: 0; padding-right: 1px;' /&gt;&lt;/a&gt;&lt;a href='https://perl.dreamwidth.org/'&gt;&lt;b&gt;perl&lt;/b&gt;&lt;/a&gt;&lt;/span&gt;, where I got suggestions to try here)&lt;br /&gt;&lt;br /&gt;ETA: &lt;a href="http://www.chiark.greenend.org.uk/~adamb/dw-thataway.pl.txt"&gt;http://www.chiark.greenend.org.uk/~adamb/dw-thataway.pl.txt&lt;/a&gt; is the current state of the script. I've tested it on a small test journal and it seems to do what it's supposed to do. If anyone's brave enough to test it on real-world data and let me have any bug reports, that'd be wonderful.&lt;br /&gt;&lt;br /&gt;&lt;img src="https://www.dreamwidth.org/tools/commentcount?user=dw_dev&amp;ditemid=69778" width="30" height="12" alt="comment count unavailable" style="vertical-align: middle;"/&gt; comments</content>
  </entry>
</feed>
