On 05/29/11 16:24, Fred Mellender wrote:
Hi!
I would like to see a general scripting capability that would have
commands for all the menu items in SCID as well as keyboard shortcuts.
As an example project: construct "mate in one" puzzles (which I have
done via the current interface to SCID, game by game):
Though a nice idea to have some sort of macro recorder, I feel that at
the moment no one has capacities to work on this. Do you? Could you
contribute the code? I fear this could get quite complex. And I'm not
sure how much use a macro recorder is in the end.
[...]
If there were a scripting capability that would include language for all
menu commands and key short cuts it would make SCID very powerful for
projects like the above. Perhaps a separate script interpreter (outside
of SCID) that could send commands to SCID (say, via STDIN) and receive
results back would be simplest to implement. If SCID would define the
command protocol, that would be enough to get us started (leaving the
script language definition and interpreter to the user community).
Well, if you want a full scale scripting language within Scid you can
just do it right now. You can even do it for years. There is no need to
invent yet another language (a wast of time anyway) and in fact not to
write a single line of code.
Just use TCL as language and use Scid as API backend. It's all there,
it's the very way how Scid is done itself. For simple examples on how to
do such things see e.g. sc_spell, sc_addmove, sc_spell, sc_import, sc_...
Doing automatic searches within the Scid database to find individual
games by some criteria is e.g. done extensively in the correspondence
chess code. (tcl/tools/correspondence.tcl) All the cc functionality
lives on top of the tcl ie. scripting layer of Scid. Not a single line
of C code is involved here. Though it integrates with Scids menues it
was in fact written almost entirely without this linkage, in a way it is
a sample of a (well, by now pretty large) Scid macro. If one drops the
requirement for NLS support, one could even move all menues and buttons
geneated right into the very module itself and it would have no
interference with Scids main code at all.
If you want to check out how such things can be done I've attached a
simple "macro" that embeds itself into Scids CC functions to provide
better blending with some functionalities my favourite chess club. This
is used as a plugin. This plugin adds it's own menu entries (in this
case to the CC window) and lives completely on it's own. It doesn't
provide NLS for that reason. (But personally I don't care about NLS
myself as long as everything is in English.)
However beware: if you do such scripting you can easily trigger side
effects and/or destroy your work. So place your favourite disclaimer
here before you proceed. You've been warned! ;)
--
Kind regards, / War is Peace.
| Freedom is Slavery.
Alexander Wagner | Ignorance is Strength.
|
| Theory : G. Orwell, "1984"
/ In practice: USA, since 2001
#=========================================================================
#
# SchemingMind.tcl: Plugin for Scids Correspondence Chess features
#
#
# This Plugin adds usefull functions in combination with
# SchemingMind Correspondence Chess Club.
#
# Plugin Code requires CC interface to be at least 1.30
#
# $Id: $
# Last change: <Sun, 2011/06/19 16:28:49 arwagner agamemnon>
# Author : Alexander Wagner
# Language : Tcl/Tk
#
#-------------------------------------------------------------------------
#
# Copyright (C) 2008 by Alexander Wagner
#
# This is free software; you can redistribute it and/or modify it
# under the terms of the GNU Genereal Public License as published
# by the Free Software Foundation; either version 2, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be usefull,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have recieved a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
#=========================================================================
#----------------------------------------------------------------------
# WSFC: Web Services for Chess
#----------------------------------------------------------------------
namespace eval WSFC {
#----------------------------------------------------------------------
# Header and footer of the SOAP-messages. Linebreaking is imporant
#
set SOAPstart {<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
}
set SOAPend {</soap:Body>
</soap:Envelope>}
#
#----------------------------------------------------------------------
#======================================================================
#
# Call up game annotations
#
#----------------------------------------------------------------------
# GetAnnotation: Called with a FEN it retrieves the available
# annotations from the server
#----------------------------------------------------------------------
proc GetAnnotation {uri username password fen aformat} {
# construct the SOAP-message for Xfcc Webservice
set xmlmessage $::Xfcc::SOAPstart
# generate the "Get my Games" call
append xmlmessage {<GetAnnotation xmlns="http://schemingmind.com/wsfc/">}
append xmlmessage "<UserName>$username</UserName>"
append xmlmessage "<Password>$password</Password>"
append xmlmessage "<EPD>$fen</EPD>"
append xmlmessage "<AnnotationFormat>$aformat</AnnotationFormat>"
append xmlmessage "</GetAnnotation>"
append xmlmessage $::Xfcc::SOAPend
# send it to the web service note the space before the charset
set token [::http::geturl $uri \
-type "text/xml; charset=\"utf-8\"" \
-query $xmlmessage]
# retrieve result
set xmlresult [::http::data $token]
return $xmlresult
}
proc GetAnnotationResponse {xml} {
set Annotation {}
# The following removes the SOAP-Envelope. tDOM does not seem to
# like it for whatever reason, but it's not needed anyway.
regsub -all {.*<GetAnnotationResult>} $xml {<GetAnnotationResult>} xml
regsub -all {</GetAnnotationResult>.*} $xml {</GetAnnotationResult>} xml
set dom [dom parse $xml]
set doc [$dom documentElement]
set aResponse [$doc selectNodes //GetAnnotationResult]
foreach answer $aResponse {
set Text [xmldecrypt [$answer selectNodes {string(Text)}]]
set Author [xmldecrypt [$answer selectNodes {string(Author)}]]
set LastUpdated [xmldecrypt [$answer selectNodes {string(LastUpdated)}]]
set Copyright [xmldecrypt [$answer selectNodes {string(Copyright)}]]
set Licence [xmldecrypt [$answer selectNodes {string(Licence)}]]
set ECO [xmldecrypt [$answer selectNodes {string(ECOCode)}]]
set Name [xmldecrypt [$answer selectNodes {string(ECOName)}]]
regsub -all {T} $LastUpdated {, } LastUpdated
regsub -all {:[0-9.]*$} $LastUpdated {} LastUpdated
regsub -all {\[B\]} $Text {} Text
regsub -all {\[I\]} $Text {} Text
regsub -all {\[/B\]} $Text {} Text
regsub -all {\[/I\]} $Text {} Text
}
lappend Annotation [list "Text" $Text ]
lappend Annotation [list "Author" $Author ]
lappend Annotation [list "LastUpdated" $LastUpdated ]
lappend Annotation [list "Copyright" $Copyright ]
lappend Annotation [list "Licence" $Licence ]
lappend Annotation [list "ECO" $ECO ]
lappend Annotation [list "Name" $Name ]
return $Annotation
}
#
#======================================================================
proc writeFile { filename data } {
if {[catch {open $filename w} OUT]} {
puts stderr "Error creating $filename does not exist"
} else {
fconfigure $OUT -translation binary
puts -nonewline $OUT $data
close $OUT
}
}
#----------------------------------------------------------------------
# Fetch a file via http
#----------------------------------------------------------------------
proc getPage { url } {
set token [::http::geturl $url]
set data [::http::data $token]
::http::cleanup $token
return $data
}
#----------------------------------------------------------------------
# Replace XML entities by their normal characters
#----------------------------------------------------------------------
proc xmldecrypt {chdata} {
foreach from {{\&} {\<} {\>} {\"} {\'}} \
to {{\&} < > {"} {'}} { ;# '"
regsub -all $from $chdata $to chdata
}
return $chdata
}
if {[catch { package require http }]} {
::splash::add "http package not found, disabeling WSFC"
set XfccInternal -1
}
if {[catch {package require tdom}]} {
::splash::add "tDOM package not found, disabeling WSFC"
set XfccInternal -1
}
}
#----------------------------------------------------------------------
namespace eval PluginSchemingMind {
set PluginName "SchemingMind"
# Hook up with SchemingMinds Game Explorer Database
set GEURL "http://schemingmind.com/gameexplorer.aspx?epd="
set MTURL "http://www.schemingmind.com/minitournamentsrch.aspx"
set FindOppURL "http://www.schemingmind.com/suggestoppnt.aspx"
set ForumsURL "http://www.schemingmind.com/forums.aspx"
set InboxURL "http://www.schemingmind.com/pminbox.aspx"
# WSFC ressources
set WSFCAnnotation "http://www.schemingmind.com/wsfc/gameexplorer.asmx"
set username "guest"
set password "guest"
set w .ccWindow
::CorrespondenceChess::updateConsole "info Loading plugin: $PluginName "
#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
proc WSFCcallGE {} {
::CorrespondenceChess::updateConsole "Fetching data from Game Explorer..."
set currentFEN [sc_pos fen]
# Search for the user id and the password on schemingmind.com
# For this to work the games have to be fetched first.
set size [expr [ array size ::Xfcc::xfccsrv ] / 4]
for {set i 0} {$i < $size } {incr i} {
if { [regexp {schemingmind.com} $::Xfcc::xfccsrv($i,1)] } {
set ::CorrespondenceChess::PluginSchemingMind::username $::Xfcc::xfccsrv($i,2)
set ::CorrespondenceChess::PluginSchemingMind::password $::Xfcc::xfccsrv($i,3)
}
}
# Fetch the annotation from the server in Plain Text format.
set xml [::CorrespondenceChess::WSFC::GetAnnotation \
$::CorrespondenceChess::PluginSchemingMind::WSFCAnnotation \
$::CorrespondenceChess::PluginSchemingMind::username \
$::CorrespondenceChess::PluginSchemingMind::password \
$currentFEN "PlainText" ]
set answer [::CorrespondenceChess::WSFC::GetAnnotationResponse $xml]
# set up the new annotation
if {[lindex [lindex $answer 6] 1] != ""} {
set annotation "[lindex [lindex $answer 6] 1] "
} else {
set annotation ""
}
if {[lindex [lindex $answer 5] 1] != ""} {
append annotation "([lindex [lindex $answer 5] 1])\n\n"
}
append annotation [lindex [lindex $answer 0] 1]
append annotation "\n\n([lindex [lindex $answer 1] 1], [lindex [lindex $answer 2] 1])"
append annotation "\n[lindex [lindex $answer 3] 1] "
append annotation [lindex [lindex $answer 4] 1]
# Check, if a Mask file is opened. If yes, add annotation to the
# mask instead of the game.
if { $::tree::mask::maskFile != "" } {
::CorrespondenceChess::updateConsole "info Updating tree mask..."
# fetch the current comment for the position
set oldComment [::tree::mask::getPositionComment]
set oldComment [ string trim $oldComment ]
append oldComment "\n\n"
# concatenate both to the new comment
set newComment $oldComment
append newComment $annotation
# Add the comment to the current mask
::tree::mask::setPositionComment $newComment
# call the comment editor window _afterwards_ (otherwise, the
# new text does not exist) for the user to be able to edit the
# commentary.
::tree::mask::addComment
} else {
# No mask is opened, therefore add the comment to the current
# game only.
::CorrespondenceChess::updateConsole "info Updating game comment..."
set comment [sc_pos getComment]
regsub -all "\n" $annotation "\n\n" annotation
if { $comment != "" } {
append comment " -- "
}
append comment $annotation
sc_pos setComment $comment
updateBoard -pgn
}
}
#----------------------------------------------------------------------
# Call the Game Explorer via a web browser
#----------------------------------------------------------------------
proc CallWWWGE {} {
::CorrespondenceChess::updateConsole "Calling Game Explorer..."
set currentFEN [sc_pos fen]
set URL "$::CorrespondenceChess::PluginSchemingMind::GEURL$currentFEN"
openURL $URL
}
#----------------------------------------------------------------------
# Call an URL and issue it's name ($tag) to the console
#----------------------------------------------------------------------
proc CallWWW { tag url } {
::CorrespondenceChess::updateConsole "Opening $tag..."
puts stderr "CallWWW $url"
openURL $url
}
#----------------------------------------------------------------------
# Add a new cascaded menu to the CC window
#----------------------------------------------------------------------
set m .ccWindow.menu
$m add cascade -label $PluginName -menu $m.schemingmind -underline 0
foreach i {schemingmind} {
menu $w.menu.$i -tearoff 0
}
#----------------------------------------------------------------------
# Call up the Game Explorer with current position
::CorrespondenceChess::updateConsole "info Hotkey: G = Add GameExplorer comments"
$m.schemingmind add command -label "Fetch Annotation" -command {
::CorrespondenceChess::PluginSchemingMind::WSFCcallGE
} -accelerator "G" -underline 0
bind $w "G" { ::CorrespondenceChess::PluginSchemingMind::WSFCcallGE }
#----------------------------------------------------------------------
# Hook up with SchemingMinds web pages for almost seemless
# integration. The default webbrowser is used to open the pages.
#----------------------------------------------------------------------
$m.schemingmind add separator
# Call up the Game Explorer with current position
::CorrespondenceChess::updateConsole "info Hotkey: g = call GameExplorer"
$m.schemingmind add command -label "Game Explorer" -command {
::CorrespondenceChess::PluginSchemingMind::CallWWWGE
} -accelerator "g" -underline 0
bind $w "g" { ::CorrespondenceChess::PluginSchemingMind::CallWWWGE }
$m.schemingmind add separator
# Go to the Inbox (Forums)
::CorrespondenceChess::updateConsole "info Hotkey: i = personal Inbox"
$m.schemingmind add command -label "Open Inbox" -command {
::CorrespondenceChess::PluginSchemingMind::CallWWW "Inbox" \
$::CorrespondenceChess::PluginSchemingMind::InboxURL
} -accelerator "i" -underline 5
bind $w "i" {
::CorrespondenceChess::PluginSchemingMind::CallWWW "Inbox" \
$::CorrespondenceChess::PluginSchemingMind::InboxURL
}
# Go to the Clubs Room (Forums)
::CorrespondenceChess::updateConsole "info Hotkey: c = Club Room"
$m.schemingmind add command -label "Club Room" -command {
::CorrespondenceChess::PluginSchemingMind::CallWWW "Club Room (Fourms)" \
$::CorrespondenceChess::PluginSchemingMind::ForumsURL
} -accelerator "c" -underline 0
bind $w "c" {
::CorrespondenceChess::PluginSchemingMind::CallWWW "Club Room (Fourms)" \
$::CorrespondenceChess::PluginSchemingMind::ForumsURL
}
$m.schemingmind add separator
# go to the Mini-tournament search page
::CorrespondenceChess::updateConsole "info Hotkey: m = Mini-tournament search"
$m.schemingmind add command -label "Mini-tournament search" -command {
::CorrespondenceChess::PluginSchemingMind::CallWWW "Mini-tournament search" \
$::CorrespondenceChess::PluginSchemingMind::MTURL
} -accelerator "m" -underline 0
bind $w "m" {
::CorrespondenceChess::PluginSchemingMind::CallWWW "Mini-tournament search" \
$::CorrespondenceChess::PluginSchemingMind::MTURL
}
# go to the Opponent Search web page
::CorrespondenceChess::updateConsole "info Hotkey: o = Opponent search"
$m.schemingmind add command -label "Opponent search" -command {
::CorrespondenceChess::PluginSchemingMind::CallWWW "opponent search" \
$::CorrespondenceChess::PluginSchemingMind::FindOppURL
} -accelerator "o" -underline 0
bind $w "o" {
::CorrespondenceChess::PluginSchemingMind::CallWWW "opponent search" \
$::CorrespondenceChess::PluginSchemingMind::FindOppURL
}
$m.schemingmind add separator
$m.schemingmind add command -label "Fetch ssp" -command {
set url "http://www.lockwood.me.uk/sm_ratings_2009_4.zip"
# set url "http://members.inode.at/786053/ratings_2009_04.ssp.tar.bz2"
set filename "/tmp/out.zip"
set data [::CorrespondenceChess::WSFC::getPage $url ]
::CorrespondenceChess::WSFC::writeFile $filename $data
}
}
------------------------------------------------------------------------------
EditLive Enterprise is the world's most technically advanced content
authoring tool. Experience the power of Track Changes, Inline Image
Editing and ensure content is compliant with Accessibility Checking.
http://p.sf.net/sfu/ephox-dev2dev
_______________________________________________
Scid-users mailing list
Scid-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/scid-users