diff options
| -rwxr-xr-x | .local/bin/i3-get-window-criteria | 40 | ||||
| -rwxr-xr-x | .local/bin/moss | 358 | ||||
| -rwxr-xr-x | .local/bin/notify_phone | 9 | 
3 files changed, 407 insertions, 0 deletions
diff --git a/.local/bin/i3-get-window-criteria b/.local/bin/i3-get-window-criteria new file mode 100755 index 0000000..f46f65e --- /dev/null +++ b/.local/bin/i3-get-window-criteria  | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | |||
| 3 | # i3-get-window-criteria - Get criteria for use with i3 config commands | ||
| 4 | |||
| 5 | # To use, run this script, then click on a window. | ||
| 6 | # Output is in the format: [<name>=<value> <name>=<value> ...] | ||
| 7 | |||
| 8 | # Known problem: when WM_NAME is used as fallback for the 'title="<string>"' criterion, | ||
| 9 | # quotes in "<string>" are not escaped properly. This is a problem with the output of `xprop`, | ||
| 10 | # reported upstream: https://bugs.freedesktop.org/show_bug.cgi?id=66807 | ||
| 11 | |||
| 12 | PROGNAME=`basename "$0"` | ||
| 13 | |||
| 14 | # Check for xwininfo and xprop | ||
| 15 | for cmd in xwininfo xprop; do | ||
| 16 | if ! which $cmd > /dev/null 2>&1; then | ||
| 17 | echo "$PROGNAME: $cmd: command not found" >&2 | ||
| 18 | exit 1 | ||
| 19 | fi | ||
| 20 | done | ||
| 21 | |||
| 22 | match_int='[0-9][0-9]*' | ||
| 23 | match_string='".*"' | ||
| 24 | match_qstring='"[^"\\]*(\\.[^"\\]*)*"' # NOTE: Adds 1 backreference | ||
| 25 | |||
| 26 | { | ||
| 27 | # Run xwininfo, get window id | ||
| 28 | window_id=`xwininfo -int | sed -nre "s/^xwininfo: Window id: ($match_int) .*$/\1/p"` | ||
| 29 | echo "id=$window_id" | ||
| 30 | |||
| 31 | # Run xprop, transform its output into i3 criteria. Handle fallback to | ||
| 32 | # WM_NAME when _NET_WM_NAME isn't set | ||
| 33 | xprop -id $window_id | | ||
| 34 | sed -nr \ | ||
| 35 | -e "s/^WM_CLASS\(STRING\) = ($match_qstring), ($match_qstring)$/instance=\1\nclass=\3/p" \ | ||
| 36 | -e "s/^WM_WINDOW_ROLE\(STRING\) = ($match_qstring)$/window_role=\1/p" \ | ||
| 37 | -e "/^WM_NAME\(STRING\) = ($match_string)$/{s//title=\1/; h}" \ | ||
| 38 | -e "/^_NET_WM_NAME\(UTF8_STRING\) = ($match_qstring)$/{s//title=\1/; h}" \ | ||
| 39 | -e '${g; p}' | ||
| 40 | } | sort | tr "\n" " " | sed -r 's/^(.*) $/[\1]\n/' | ||
diff --git a/.local/bin/moss b/.local/bin/moss new file mode 100755 index 0000000..556e623 --- /dev/null +++ b/.local/bin/moss  | |||
| @@ -0,0 +1,358 @@ | |||
| 1 | #!/usr/bin/perl | ||
| 2 | # | ||
| 3 | # Please read all the comments down to the line that says "TOP". | ||
| 4 | # These comments are divided into three sections: | ||
| 5 | # | ||
| 6 | # 1. usage instructions | ||
| 7 | # 2. installation instructions | ||
| 8 | # 3. standard copyright | ||
| 9 | # | ||
| 10 | # Feel free to share this script with other instructors of programming | ||
| 11 | # classes, but please do not place the script in a publicly accessible | ||
| 12 | # place. Comments, questions, and bug reports should be sent to | ||
| 13 | # moss-request@moss.stanford.edu. | ||
| 14 | # | ||
| 15 | # IMPORTANT: This script is known to work on Unix and on Windows using Cygwin. | ||
| 16 | # It is not known to work on other ways of using Perl under Windows. If the | ||
| 17 | # script does not work for you under Windows, you can try the email-based | ||
| 18 | # version for Windows (available on the Moss home page). | ||
| 19 | # | ||
| 20 | |||
| 21 | # | ||
| 22 | # Section 1. Usage instructions | ||
| 23 | # | ||
| 24 | # moss [-l language] [-d] [-b basefile1] ... [-b basefilen] [-m #] [-c "string"] file1 file2 file3 ... | ||
| 25 | # | ||
| 26 | # The -l option specifies the source language of the tested programs. | ||
| 27 | # Moss supports many different languages; see the variable "languages" below for the | ||
| 28 | # full list. | ||
| 29 | # | ||
| 30 | # Example: Compare the lisp programs foo.lisp and bar.lisp: | ||
| 31 | # | ||
| 32 | # moss -l lisp foo.lisp bar.lisp | ||
| 33 | # | ||
| 34 | # | ||
| 35 | # The -d option specifies that submissions are by directory, not by file. | ||
| 36 | # That is, files in a directory are taken to be part of the same program, | ||
| 37 | # and reported matches are organized accordingly by directory. | ||
| 38 | # | ||
| 39 | # Example: Compare the programs foo and bar, which consist of .c and .h | ||
| 40 | # files in the directories foo and bar respectively. | ||
| 41 | # | ||
| 42 | # moss -d foo/*.c foo/*.h bar/*.c bar/*.h | ||
| 43 | # | ||
| 44 | # Example: Each program consists of the *.c and *.h files in a directory under | ||
| 45 | # the directory "assignment1." | ||
| 46 | # | ||
| 47 | # moss -d assignment1/*/*.h assignment1/*/*.c | ||
| 48 | # | ||
| 49 | # | ||
| 50 | # The -b option names a "base file". Moss normally reports all code | ||
| 51 | # that matches in pairs of files. When a base file is supplied, | ||
| 52 | # program code that also appears in the base file is not counted in matches. | ||
| 53 | # A typical base file will include, for example, the instructor-supplied | ||
| 54 | # code for an assignment. Multiple -b options are allowed. You should | ||
| 55 | # use a base file if it is convenient; base files improve results, but | ||
| 56 | # are not usually necessary for obtaining useful information. | ||
| 57 | # | ||
| 58 | # IMPORTANT: Unlike previous versions of moss, the -b option *always* | ||
| 59 | # takes a single filename, even if the -d option is also used. | ||
| 60 | # | ||
| 61 | # Examples: | ||
| 62 | # | ||
| 63 | # Submit all of the C++ files in the current directory, using skeleton.cc | ||
| 64 | # as the base file: | ||
| 65 | # | ||
| 66 | # moss -l cc -b skeleton.cc *.cc | ||
| 67 | # | ||
| 68 | # Submit all of the ML programs in directories asn1.96/* and asn1.97/*, where | ||
| 69 | # asn1.97/instructor/example.ml and asn1.96/instructor/example.ml contain the base files. | ||
| 70 | # | ||
| 71 | # moss -l ml -b asn1.97/instructor/example.ml -b asn1.96/instructor/example.ml -d asn1.97/*/*.ml asn1.96/*/*.ml | ||
| 72 | # | ||
| 73 | # The -m option sets the maximum number of times a given passage may appear | ||
| 74 | # before it is ignored. A passage of code that appears in many programs | ||
| 75 | # is probably legitimate sharing and not the result of plagiarism. With -m N, | ||
| 76 | # any passage appearing in more than N programs is treated as if it appeared in | ||
| 77 | # a base file (i.e., it is never reported). Option -m can be used to control | ||
| 78 | # moss' sensitivity. With -m 2, moss reports only passages that appear | ||
| 79 | # in exactly two programs. If one expects many very similar solutions | ||
| 80 | # (e.g., the short first assignments typical of introductory programming | ||
| 81 | # courses) then using -m 3 or -m 4 is a good way to eliminate all but | ||
| 82 | # truly unusual matches between programs while still being able to detect | ||
| 83 | # 3-way or 4-way plagiarism. With -m 1000000 (or any very | ||
| 84 | # large number), moss reports all matches, no matter how often they appear. | ||
| 85 | # The -m setting is most useful for large assignments where one also a base file | ||
| 86 | # expected to hold all legitimately shared code. The default for -m is 10. | ||
| 87 | # | ||
| 88 | # Examples: | ||
| 89 | # | ||
| 90 | # moss -l pascal -m 2 *.pascal | ||
| 91 | # moss -l cc -m 1000000 -b mycode.cc asn1/*.cc | ||
| 92 | # | ||
| 93 | # | ||
| 94 | # The -c option supplies a comment string that is attached to the generated | ||
| 95 | # report. This option facilitates matching queries submitted with replies | ||
| 96 | # received, especially when several queries are submitted at once. | ||
| 97 | # | ||
| 98 | # Example: | ||
| 99 | # | ||
| 100 | # moss -l scheme -c "Scheme programs" *.sch | ||
| 101 | # | ||
| 102 | # The -n option determines the number of matching files to show in the results. | ||
| 103 | # The default is 250. | ||
| 104 | # | ||
| 105 | # Example: | ||
| 106 | # moss -c java -n 200 *.java | ||
| 107 | # The -x option sends queries to the current experimental version of the server. | ||
| 108 | # The experimental server has the most recent Moss features and is also usually | ||
| 109 | # less stable (read: may have more bugs). | ||
| 110 | # | ||
| 111 | # Example: | ||
| 112 | # | ||
| 113 | # moss -x -l ml *.ml | ||
| 114 | # | ||
| 115 | |||
| 116 | |||
| 117 | # | ||
| 118 | # Section 2. Installation instructions. | ||
| 119 | # | ||
| 120 | # You may need to change the very first line of this script | ||
| 121 | # if perl is not in /usr/bin on your system. Just replace /usr/bin | ||
| 122 | # with the pathname of the directory where perl resides. | ||
| 123 | # | ||
| 124 | |||
| 125 | # | ||
| 126 | # 3. Standard Copyright | ||
| 127 | # | ||
| 128 | #Copyright (c) 1997 The Regents of the University of California. | ||
| 129 | #All rights reserved. | ||
| 130 | # | ||
| 131 | #Permission to use, copy, modify, and distribute this software for any | ||
| 132 | #purpose, without fee, and without written agreement is hereby granted, | ||
| 133 | #provided that the above copyright notice and the following two | ||
| 134 | #paragraphs appear in all copies of this software. | ||
| 135 | # | ||
| 136 | #IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR | ||
| 137 | #DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT | ||
| 138 | #OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF | ||
| 139 | #CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 140 | # | ||
| 141 | #THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, | ||
| 142 | #INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY | ||
| 143 | #AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS | ||
| 144 | #ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO | ||
| 145 | #PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | ||
| 146 | # | ||
| 147 | # | ||
| 148 | # STOP. It should not be necessary to change anything below this line | ||
| 149 | # to use the script. | ||
| 150 | # | ||
| 151 | use IO::Socket; | ||
| 152 | |||
| 153 | # | ||
| 154 | # As of the date this script was written, the following languages were supported. This script will work with | ||
| 155 | # languages added later however. Check the moss website for the full list of supported languages. | ||
| 156 | # | ||
| 157 | @languages = ("c", "cc", "java", "ml", "pascal", "ada", "lisp", "scheme", "haskell", "fortran", "ascii", "vhdl", "perl", "matlab", "python", "mips", "prolog", "spice", "vb", "csharp", "modula2", "a8086", "javascript", "plsql", "verilog"); | ||
| 158 | |||
| 159 | $server = 'moss.stanford.edu'; | ||
| 160 | $port = '7690'; | ||
| 161 | $noreq = "Request not sent."; | ||
| 162 | $usage = "usage: moss [-x] [-l language] [-d] [-b basefile1] ... [-b basefilen] [-m #] [-c \"string\"] file1 file2 file3 ..."; | ||
| 163 | |||
| 164 | # | ||
| 165 | # The userid is used to authenticate your queries to the server; don't change it! | ||
| 166 | # | ||
| 167 | $userid=173681612; | ||
| 168 | |||
| 169 | # | ||
| 170 | # Process the command line options. This is done in a non-standard | ||
| 171 | # way to allow multiple -b's. | ||
| 172 | # | ||
| 173 | $opt_l = "c"; # default language is c | ||
| 174 | $opt_m = 10; | ||
| 175 | $opt_d = 0; | ||
| 176 | $opt_x = 0; | ||
| 177 | $opt_c = ""; | ||
| 178 | $opt_n = 250; | ||
| 179 | $bindex = 0; # this becomes non-zero if we have any base files | ||
| 180 | |||
| 181 | while (@ARGV && ($_ = $ARGV[0]) =~ /^-(.)(.*)/) { | ||
| 182 | ($first,$rest) = ($1,$2); | ||
| 183 | |||
| 184 | shift(@ARGV); | ||
| 185 | if ($first eq "d") { | ||
| 186 | $opt_d = 1; | ||
| 187 | next; | ||
| 188 | } | ||
| 189 | if ($first eq "b") { | ||
| 190 | if($rest eq '') { | ||
| 191 | die "No argument for option -b.\n" unless @ARGV; | ||
| 192 | $rest = shift(@ARGV); | ||
| 193 | } | ||
| 194 | $opt_b[$bindex++] = $rest; | ||
| 195 | next; | ||
| 196 | } | ||
| 197 | if ($first eq "l") { | ||
| 198 | if ($rest eq '') { | ||
| 199 | die "No argument for option -l.\n" unless @ARGV; | ||
| 200 | $rest = shift(@ARGV); | ||
| 201 | } | ||
| 202 | $opt_l = $rest; | ||
| 203 | next; | ||
| 204 | } | ||
| 205 | if ($first eq "m") { | ||
| 206 | if($rest eq '') { | ||
| 207 | die "No argument for option -m.\n" unless @ARGV; | ||
| 208 | $rest = shift(@ARGV); | ||
| 209 | } | ||
| 210 | $opt_m = $rest; | ||
| 211 | next; | ||
| 212 | } | ||
| 213 | if ($first eq "c") { | ||
| 214 | if($rest eq '') { | ||
| 215 | die "No argument for option -c.\n" unless @ARGV; | ||
| 216 | $rest = shift(@ARGV); | ||
| 217 | } | ||
| 218 | $opt_c = $rest; | ||
| 219 | next; | ||
| 220 | } | ||
| 221 | if ($first eq "n") { | ||
| 222 | if($rest eq '') { | ||
| 223 | die "No argument for option -n.\n" unless @ARGV; | ||
| 224 | $rest = shift(@ARGV); | ||
| 225 | } | ||
| 226 | $opt_n = $rest; | ||
| 227 | next; | ||
| 228 | } | ||
| 229 | if ($first eq "x") { | ||
| 230 | $opt_x = 1; | ||
| 231 | next; | ||
| 232 | } | ||
| 233 | # | ||
| 234 | # Override the name of the server. This is used for testing this script. | ||
| 235 | # | ||
| 236 | if ($first eq "s") { | ||
| 237 | $server = shift(@ARGV); | ||
| 238 | next; | ||
| 239 | } | ||
| 240 | # | ||
| 241 | # Override the port. This is used for testing this script. | ||
| 242 | # | ||
| 243 | if ($first eq "p") { | ||
| 244 | $port = shift(@ARGV); | ||
| 245 | next; | ||
| 246 | } | ||
| 247 | die "Unrecognized option -$first. $usage\n"; | ||
| 248 | } | ||
| 249 | |||
| 250 | # | ||
| 251 | # Check a bunch of things first to ensure that the | ||
| 252 | # script will be able to run to completion. | ||
| 253 | # | ||
| 254 | |||
| 255 | # | ||
| 256 | # Make sure all the argument files exist and are readable. | ||
| 257 | # | ||
| 258 | print "Checking files . . . \n"; | ||
| 259 | $i = 0; | ||
| 260 | while($i < $bindex) | ||
| 261 | { | ||
| 262 | die "Base file $opt_b[$i] does not exist. $noreq\n" unless -e "$opt_b[$i]"; | ||
| 263 | die "Base file $opt_b[$i] is not readable. $noreq\n" unless -r "$opt_b[$i]"; | ||
| 264 | die "Base file $opt_b is not a text file. $noreq\n" unless -T "$opt_b[$i]"; | ||
| 265 | $i++; | ||
| 266 | } | ||
| 267 | foreach $file (@ARGV) | ||
| 268 | { | ||
| 269 | die "File $file does not exist. $noreq\n" unless -e "$file"; | ||
| 270 | die "File $file is not readable. $noreq\n" unless -r "$file"; | ||
| 271 | die "File $file is not a text file. $noreq\n" unless -T "$file"; | ||
| 272 | } | ||
| 273 | |||
| 274 | if ("@ARGV" eq '') { | ||
| 275 | die "No files submitted.\n $usage"; | ||
| 276 | } | ||
| 277 | print "OK\n"; | ||
| 278 | |||
| 279 | # | ||
| 280 | # Now the real processing begins. | ||
| 281 | # | ||
| 282 | |||
| 283 | |||
| 284 | $sock = new IO::Socket::INET ( | ||
| 285 | PeerAddr => $server, | ||
| 286 | PeerPort => $port, | ||
| 287 | Proto => 'tcp', | ||
| 288 | ); | ||
| 289 | die "Could not connect to server $server: $!\n" unless $sock; | ||
| 290 | $sock->autoflush(1); | ||
| 291 | |||
| 292 | sub read_from_server { | ||
| 293 | $msg = <$sock>; | ||
| 294 | print $msg; | ||
| 295 | } | ||
| 296 | |||
| 297 | sub upload_file { | ||
| 298 | local ($file, $id, $lang) = @_; | ||
| 299 | # | ||
| 300 | # The stat function does not seem to give correct filesizes on windows, so | ||
| 301 | # we compute the size here via brute force. | ||
| 302 | # | ||
| 303 | open(F,$file); | ||
| 304 | $size = 0; | ||
| 305 | while (<F>) { | ||
| 306 | $size += length($_); | ||
| 307 | } | ||
| 308 | close(F); | ||
| 309 | |||
| 310 | print "Uploading $file ..."; | ||
| 311 | open(F,$file); | ||
| 312 | $file =~s/\s/\_/g; # replace blanks in filename with underscores | ||
| 313 | print $sock "file $id $lang $size $file\n"; | ||
| 314 | while (<F>) { | ||
| 315 | print $sock $_; | ||
| 316 | } | ||
| 317 | close(F); | ||
| 318 | print "done.\n"; | ||
| 319 | } | ||
| 320 | |||
| 321 | |||
| 322 | print $sock "moss $userid\n"; # authenticate user | ||
| 323 | print $sock "directory $opt_d\n"; | ||
| 324 | print $sock "X $opt_x\n"; | ||
| 325 | print $sock "maxmatches $opt_m\n"; | ||
| 326 | print $sock "show $opt_n\n"; | ||
| 327 | |||
| 328 | # | ||
| 329 | # confirm that we have a supported languages | ||
| 330 | # | ||
| 331 | print $sock "language $opt_l\n"; | ||
| 332 | $msg = <$sock>; | ||
| 333 | chop($msg); | ||
| 334 | if ($msg eq "no") { | ||
| 335 | print $sock "end\n"; | ||
| 336 | die "Unrecognized language $opt_l."; | ||
| 337 | } | ||
| 338 | |||
| 339 | |||
| 340 | # upload any base files | ||
| 341 | $i = 0; | ||
| 342 | while($i < $bindex) { | ||
| 343 | &upload_file($opt_b[$i++],0,$opt_l); | ||
| 344 | } | ||
| 345 | |||
| 346 | $setid = 1; | ||
| 347 | foreach $file (@ARGV) { | ||
| 348 | &upload_file($file,$setid++,$opt_l); | ||
| 349 | } | ||
| 350 | |||
| 351 | print $sock "query 0 $opt_c\n"; | ||
| 352 | print "Query submitted. Waiting for the server's response.\n"; | ||
| 353 | &read_from_server(); | ||
| 354 | print $sock "end\n"; | ||
| 355 | close($sock); | ||
| 356 | |||
| 357 | |||
| 358 | |||
diff --git a/.local/bin/notify_phone b/.local/bin/notify_phone new file mode 100755 index 0000000..6228f73 --- /dev/null +++ b/.local/bin/notify_phone  | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | |||
| 3 | TOKEN=795983515:AAHAPgakm-BbRKNodF9a0z_OH2VDsIxpm_Q | ||
| 4 | CHAT_ID=4903620 | ||
| 5 | INPUT=$@ | ||
| 6 | MESSAGE=${INPUT:-"all done"} | ||
| 7 | URL="https://api.telegram.org/bot$TOKEN/sendMessage" | ||
| 8 | |||
| 9 | curl -s -X POST "$URL" -d chat_id="${CHAT_ID}" -d text="${MESSAGE}" | ||
