Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??
Welcome to Part 3 of How to write apps for macOS/OSX in Perl! This app protects Internet Privacy by regularly changing DNS servers. It's designed to run constantly in the background. I use it all day every day for the past 2 months.

This edition demonstrates how to:

  1. Write a very useful application!
  2. Use Perl to create, read and write a config file.
  3. Easily edit the config file.
  4. Configure multiple run time variables.
  5. Pass variables between Applescript and Perl.
  6. Handle errors and bad input.
  7. Use core Perl modules.

See Part 1 to get started with Perl and the built-in Mac devtool Automator,
and the demo Perl app for Mac: Perl ASN Check

See Part 2 for more techniques to integrate Perl into Mac with Applescript,
and the demo Perl app for Mac: Perl Version Tool

This ~150 liner is ~120 lines of Applescript GUI logic linked to ~30 lines of core Perl code in the form of 3 one-liners! Hopefully our Mac-centric monks will pick up these techniques to write and share Mac apps to improve computing experiences with Perl! Remember: All Macs Have Perl!

    Compile this code with the instructions in Part 1
    to produce a 1.3MB portable binary application:


-- Set random DNS server every n minutes. # Demonstration Apple macOS/OSX app in AppleScript and Perl # Posted to by Anonymous Monk 6/16/2018 # Node: How to write apps for macOS/OSX in Perl! Part 3: Random DNS Se +rver -- Part 1: Perl ASN Check -- Part 2: Perl Version Tool # DEFAULT DNS SERVERS: # = Cloudflare # = Google # = Fourth Estate Zero Knowledge set DNS to "" set DEFAULT_NETWORK to "Wi-Fi" set TITLE to "Random DNS Server" # CREATE AND/OR READ CONFIGURATION FILE: # 1. PASS APPLESCRIPT VARIABLES TO PERL -> # 2. SEND PERL VARIABLES TO APPLESCRIPT <- # 3. AND THAT LAST LINE... try set INI to do shell script "printf $HOME" & "/.dns.random.config" set CFG to do shell script " perl -Mautodie -we ' my $config = qq~" & INI & "~; if (-e $config) { open my $fh, q~<~, $config; @_ = <$fh>; close $fh; @_ = grep /\\S+/, @_; print @_; } else { open my $fh, q~>~, $config; print $fh qq~" & DNS & "~; close $fh; print qq~" & DNS & "~; } ' " on error oops display alert oops as critical end try set DNS to CFG # RUNTIME CONFIG LOOP repeat try set TXT to "DNS Servers: " & DNS & " Minutes between change? (blank to exit)" set EAE to "EXIT AND EDIT CONFIG" # GET DIALOG OBJECT CONTAINING INPUT AND CLICKED BUTTON VALUE set DUR to display dialog TXT with title TITLE default answer +"" buttons {EAE, "OK"} default button 2 set DUR_text to text returned of DUR as number set DUR_button to button returned of DUR if DUR_button is EAE then # EDIT CONFIG try do shell script "open -a TextEdit " & INI & "" return # EXIT on error oops display alert oops as critical return # EXIT end try end if if DUR_text is 0 then return # EXIT set DUR to DUR_text set NETS to do shell script "networksetup -listallnetworkservi +ces" set TXT to "Network Interfaces: " & NETS & " Network?" set NETWORK to text returned of (display dialog TXT with title + TITLE default answer DEFAULT_NETWORK buttons {"OK"} default button 1 +) try # DOES NETWORK EXIST? set hmm to do shell script " perl -we ' @_ = qx/networksetup -getinfo " & NETWORK & "/; $_ = join qq~\\n~, @_; print /Error/ ? 0 : 1; ' " on error oops display alert oops as critical return # EXIT end try if hmm as number is equal to 0 then display notification "Network not found! Exit..." with tit +le TITLE return # EXIT end if exit repeat # EXIT CONFIG LOOP on error oops display notification "This shouldn't happen!" with title TITLE return # EXIT end try end repeat # END CONFIG LOOP set MSG to button returned of (display dialog "Notification of change? +" buttons {"No", "Yes"} default button 2) # END CONFIG # MAIN EVENT LOOP repeat try # Use perl to read last line of resolv.conf as current DNS ser +ver. # Exclude current server and shuffle list to get new value. # Set new server and return the old and new values to applescr +ipt. set PERL to do shell script " perl -MList::Util=shuffle -Mautodie -we ' open my $fh, q~<~, q~/private/etc/resolv.conf~; chomp(@_ = <$fh>); close $fh; $_ = pop @_; my (undef,$cur) = split q~ ~; $_ = qq~" & DNS & "~; @_ = split /\\s+/; @_ = grep !/$cur/, @_; @_ = shuffle @_; my $new = pop @_; system(qq~networksetup -setdnsservers " & NETWORK & " +$new~); print qq~$cur $new~; ' " on error oops display alert oops as critical end try # AN APPLESCRIPT SPLIT set text item delimiters to {" "} set {CUR, NEW} to text items 1 thru 2 of PERL if MSG is "Yes" then display notification "DNS changed from " & CUR & " to " & NEW +with title TITLE end if delay ((DUR as integer) * 60) end repeat # MADE IN USA (This program, Perl, Apple, Me!) # b9ce5dcd671f9647fb86a6f3709a572ffd6e2aa490c005300585a555fabf9ce8 # 060c38ad8715a6a2381cc653ad5a7dd1815f3cf990c31594b4a1b20ef4fc9d27

In reply to How to write apps for macOS/OSX in Perl! Part 3: Random DNS Server by Anonymous Monk

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?

What's my password?
Create A New User
Domain Nodelet?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (3)
As of 2022-11-28 14:22 GMT
Find Nodes?
    Voting Booth?