GithubHelp home page GithubHelp logo

alma-slipsomat's Introduction

⚠️ Archived

This repository has been archived on Oct 14, 2022. Unfortunately we did not have the time and resources to update the tool after a breaking change in Alma in 2019 (#40).

We're not aware of any good alternatives at the moment, but if https://ideas.exlibrisgroup.com/forums/308173-alma/suggestions/12471084-synchronizing-xsl-templates-with-external-systems is implemented, it should be much easier to create a synchronization tool in the future.

Slipsomat

PyPI PyPI - Python Version PyPI - License

slipsomat is a small tool for pulling and pushing letters to Alma using Selenium browser automation. It allows to you to keep an up-to-date local copy of all the letters, so you can keep them under version control. And by storing checksums of all the letters, it can warn you if you're about to overwrite a letter that has been modified by someone else without pulling in their changes.

This tool exists because Alma doesn't provide a way to synchronize the letters, only a web form to edit them. With over 100 different letters, editing them using a web form (with no syntax highlighting) is very tedious. We have also brought this up on Ideas Exchange – feel free to add your vote to our idea there.

Setup

Slipsomat should work with Python 3.5 and later on most platforms. Please use our issue tracker to report any problems.

Install with pip:

pip install -U slipsomat

Once installed, you can run slipsomat from any directory containing a slipsomat.cfg config file. To get started, create an empty directory with a slipsomat.cfg file with the following contents:

[login]
auth_type=
domain=
instance=
institution=
username=
password=

[selenium]
browser=firefox
default_timeout=20

[window]
width=1300
height=700

where you fill in the blank values.

  • Set auth_type=Feide if you authenticate using Feide SAML. Set auth_type=SAML for Shibboleth or other SAML providers (submit an issue if it doesn't work with your provider!). Set auth_type=basic to use the standard Alma login.
  • domain is your Feide domain, e.g. uio.no. If you don't use Feide as your SAML provider, you can leave this empty.
  • instance is the Alma instance name, which is the first part of your ALMA URL. If your Alma URL is bibsys-k.alma.exlibrisgroup.com, then bibsys-k is the instance name.
  • institution the Alma institution name, e.g. 47BIBSYS_UBO
  • username is your username.
  • password can be left blank if you want to be asked for it each time. This is the recommended solution, since the password is stored in plain text.
  • browser can be set to firefox, chrome or phantomjs. The corresponding driver must be installed (GeckoDriver for Firefox, ChromeDriver for Chrome). I've had success with all three browsers, but from time to time a browser can start crashing or freezing at some point. First thing to try then is to upgrade both Selenium and the browser driver. If there's still problems, switch to another browser for some time. If that doesn't help, there might be an issue with slipsomat. Please file an issue.

Debugging

If you have inquirer installed (does not work on Windows), slipsomat will give you some options for starting a debug session if the script crashes.

Getting started

The slipsomat command will give you an interactive shell where you can type various commands. Type help for an overview.

To get started in an empty directory, type pull to pull in all the XSLT files from your Alma instance and store them in a folder named xsl (will be created if not there already). Optionally, type defaults to pull in all default letters too. Note that a status.json file is also created. This holds the checksums for all the letters, allowing the script to easily keep track of which files have been modified (locally or in Alma).

Once you have a directory with all your files you're free to put them under version control if you like. Here's the repo we use for our files: https://github.com/scriptotek/alma-letters-ubo

Workflow

In a workspace directory (a directory having a slipsomat.cfg file):

  1. Start by doing git pull to pull in changes from other users.

  2. slipsomat to start the script

  3. Optional: the slipsomat command pull will check if any files have been updated directly in Alma (without using slipsomat), fetch those and update status.json. Comparison is done by comparing the update date in Alma with the update date in status.json. Alma does not provide time granularity for updates, only date, so for files that have been modified today, the script will open the letter in Alma to get the text and calculate a checksum to compare with the checksum in status.json. Note: If you skip this step, slipsomat will still warn you if you try to push a letter that have been modified remotely (checksums not matching), but then you will have to merge manually.

  4. After having made modifications to one or more letters, run the slipsomat command push to push the updates to Alma. Comparison is done by comparing checksums of the local files with the checksums in status.json. Before making any changes, the script will print a list of files and confirm that you want to upload these.

  5. After having tested the modifications, do a git commit (remember to include the updated status.json) and git push

The shell has a command history, and tab completion. For example test Ful<tab><tab>.

Updating default letters

  • Use the slipsomat command defaults to pull in all default letters. Note that the command takes quite some time to run, since all letters have to be checked as Alma provides no information whatsoever on when the default letters were last updated.

Testing the output of a letter

Alma lets you test the output on the Notification Template page, but doing this manually each time is boring, so slipsomat provides you with the test command to automate that.

Create a folder called "test-data" in the same folder as the slipsomat.cfg file. Add one or more XML files you want to test there.

Start slipsomat and run the command

test filename.xml

where filename.xml is a file in the "test-data" folder. This will upload the XML file to the Notification Template page and store the resulting HTML output and a screenshot in the "test-data" folder.

To test multiple files at the same time, you can use Unix style pathname pattern expansion ("globbing"). E.g. to test all XML files in the "test-data" folder, use the * wildcard character:

test *.xml

By default, the command will use English as the letter language. To test another language, just append @ and the language code to the filename. Example:

test filename.xml@nn

You can even test multiple languages in one go by specifying multiple language codes separated by comma like so:

test filename.xml@en,no,nn

This can also be used in combination with globbing. To test all XML files in the "test-data" folder in three languages:

test *.xml@en,no,nn

See also

Development

Editable install

If you want an editable install that you can hack on yourself:

git clone https://github.com/scriptotek/alma-slipsomat.git
cd alma-slipsomat
pip install -U -e .

Using slipsomat as a Python library

Given that you have created a slipsomat.cfg file, here's how to start experimenting:

from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from slipsomat.worker import Worker
from slipsomat.slipsomat import TemplateConfigurationTable

worker = Worker('slipsomat.cfg')

# Start the browser and log in using the credentials from slipsomat.cfg
worker.connect()

# Open and parse the letters table
table = TemplateConfigurationTable(worker)

# Open the default version of the SmsFulCancelRequestLetter letter
table.open_default_letter('xsl/letters/sms/SmsFulCancelRequestLetter.xsl')

# Use Selenium to click some element
wait = worker.waiter()
element = wait.until(EC.element_to_be_clickable((By.XPATH, '//button[@aria-label="Open Alma configuration"]')))
element.click()

Note: During development, it might be a good idea to set default_timeout in slipsomat.cfg to a small value (like 3 seconds) to avoid having to wait a long time every time you write a wrong selector.

alma-slipsomat's People

Contributors

daniels avatar danmichaelo avatar ewinge avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

alma-slipsomat's Issues

Running defaults with non-pulled modifications in Alma will update modified date in status.json without actually pulling the changes

Hi,

I just noticed that after running defaults, pull wouldn't retrieve files I knew were changed in Alma.

Looking at the diff of status.json after the defaults command, the modified date was changed for these files, but the checksum was not and the modified files had not been fetched. Subsequently running pull would first crash slipsomat (possibly not related, but happened both on the first run and when I reproduced the issue) and after restarting, pull reported that "0 of 113 files contained new modifications".

Reverting these lines in status.json solved the issue for me, and of course there is a workaround in always running pull before defaults.

Just in case the crash is related, here are the last few lines of the output:

- header.xsl (2017-06-08)                                                                       - header.xsl (2017-06-08)                                      no changes                       - header.xsl (2017-06-08)                                      no changes
- footer.xsl (2017-06-08)                                                                       - footer.xsl (2017-06-08)                                      no changes                       - footer.xsl (2017-06-08)                                      no changes
- WebhookFailureLetter.xsl (-)                                                                  - WebhookFailureLetter.xsl (-)                                 
Exception: 'modified'
Traceback (most recent call last):
  File "/Users/dan/tmp/alma-letters/.direnv/python-2.7.14/lib/python2.7/site-packages/slipsomat-0.1.0-py2.7.egg/slipsomat/slipsomat.py", line 1079, in execute
    function(self.browser, *args)
  File "/Users/dan/tmp/alma-letters/.direnv/python-2.7.14/lib/python2.7/site-packages/slipsomat-0.1.0-py2.7.egg/slipsomat/slipsomat.py", line 716, in pull
    if letter.remote_modified():
  File "/Users/dan/tmp/alma-letters/.direnv/python-2.7.14/lib/python2.7/site-packages/slipsomat-0.1.0-py2.7.egg/slipsomat/slipsomat.py", line 517, in remote_modified
    if os.path.exists(self.filename) and self.modified == self.table.status.letters[self.filename]['modified'] and self.modified != today:
KeyError: 'modified'
Please "pip install inquirer" if you would like more debug options

InterestedInLetter

Det er latterlig lite informasjon om dokumentet i dette brevet. Én ting er at det ikke er en lenke til dokumentet i originalbrevet, men det er ikke MMS-id i XML-en heller, så vi kan ikke generere en lenke til Oria annet enn basert på fritekstsøk på strengsuppen:

<title>Cybernetics - the Macy Conferences 1946-1953 the complete transactions edited by Claus Pias, Zurich ;Berlin, Diaphanes, 2016, 3037345985, ISBN</title>

push: timeout kicks in early. (sandbox takes forever)

The Sandbox is extremely slow.
Slipsomat has long since given up when the sandbox eventually returns from saving the first file.
The file does get saved successfully, leaving the checksums invalid.

A push cycle therefore goes like this
(for every file changed)

  • push file
  • watch slipsomat die
  • wait for the browser to return to life
  • pull files
  • acknowledge that there are conflicting changes/checksums
  • enjoy the updated checksum
  • rinse and repeat for the next file in the queue
...
- header.xsl (19/02/2018)                                      saving...                               
Exception: Message: 

Traceback (most recent call last):
  File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/slipsomat-0.1.0-py3.6.egg/slipsomat/slipsomat.py", line 1079, in execute
    function(self.browser, *args)
  File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/slipsomat-0.1.0-py3.6.egg/slipsomat/slipsomat.py", line 805, in push
    if letter.push():
  File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/slipsomat-0.1.0-py3.6.egg/slipsomat/slipsomat.py", line 692, in push
    EC.presence_of_element_located((By.CSS_SELECTOR, ".typeD table"))
  File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/selenium-3.9.0-py3.6.egg/selenium/webdriver/support/wait.py", line 80, in until
    raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message: 

[?] Now what?: Exit
   Restart browser
   Debug with ipdb
   Debug with pdb
 > Exit

test command

Testing templates in Alma's notification template is cumbersome. It would be useful with a test command for automated testing. This requires access to XML test data.This can be accomplished in different ways:

  • a configurable path to an XML folder
  • include XML data in this project. Since the data files include personal data, the repository must then be made private

pull/push crashes on new UI

From the looks of it, it bails out on not being able to read the date, both in production and in sandbox. (UI language set to english)

slipsomat> pull
Reading table... 
Exception: Table mismatch: 113 filenames, 0 dates
Traceback (most recent call last):
  File "~/.pyenv/versions/3.6.3/lib/python3.6/site-packages/slipsomat-0.1.0-py3.6.egg/slipsomat/slipsomat.py", line 1074, in execute
    function(self.browser, *args)
  File "~/.pyenv/versions/3.6.3/lib/python3.6/site-packages/slipsomat-0.1.0-py3.6.egg/slipsomat/slipsomat.py", line 706, in pull
    table = browser.get_template_table()
  File "~/.pyenv/versions/3.6.3/lib/python3.6/site-packages/slipsomat-0.1.0-py3.6.egg/slipsomat/slipsomat.py", line 247, in get_template_table
    self._template_table = TemplateTable(self)
  File "~/.pyenv/versions/3.6.3/lib/python3.6/site-packages/slipsomat-0.1.0-py3.6.egg/slipsomat/slipsomat.py", line 316, in __init__
    self.rows = self.parse_rows()
  File "~/.pyenv/versions/3.6.3/lib/python3.6/site-packages/slipsomat-0.1.0-py3.6.egg/slipsomat/slipsomat.py", line 362, in parse_rows
    raise RuntimeError('Table mismatch: %d filenames, %d dates' % (len(filenames), len(dates)))
RuntimeError: Table mismatch: 113 filenames, 0 dates

test command fails with chromedriver

slipsomat hangs when requesting browser.driver.current_url for the popup window using chromedriver 2.34.522932. Works in firefox and phantomjs.

[1/1] Testing "borrow1.xml" using language "English"
^CTraceback (most recent call last):
  File "/Users/danmichael/.pyenv/versions/3.5.1/bin/slipsomat", line 11, in <module>
    load_entry_point('slipsomat', 'console_scripts', 'slipsomat')()
  File "/Users/danmichael/projects/scriptotek/alma-slipsomat/slipsomat/slipsomat.py", line 1085, in main
    Shell(browser).cmdloop()
  File "/Users/danmichael/.pyenv/versions/3.5.1/lib/python3.5/cmd.py", line 138, in cmdloop
    stop = self.onecmd(line)
  File "/Users/danmichael/.pyenv/versions/3.5.1/lib/python3.5/cmd.py", line 217, in onecmd
    return func(arg)
  File "/Users/danmichael/projects/scriptotek/alma-slipsomat/slipsomat/slipsomat.py", line 1008, in do_test
    self.execute(test_XML, *arg.split('@'))
  File "/Users/danmichael/projects/scriptotek/alma-slipsomat/slipsomat/slipsomat.py", line 1061, in execute
    function(self.browser, *args)
  File "/Users/danmichael/projects/scriptotek/alma-slipsomat/slipsomat/slipsomat.py", line 890, in test_XML
    if 'beanContentParam=htmlContent' in browser.driver.current_url:
  File "/Users/danmichael/.pyenv/versions/3.5.1/lib/python3.5/site-packages/selenium/webdriver/remote/webdriver.py", line 574, in current_url
    return self.execute(Command.GET_CURRENT_URL)['value']
  File "/Users/danmichael/.pyenv/versions/3.5.1/lib/python3.5/site-packages/selenium/webdriver/remote/webdriver.py", line 306, in execute
    response = self.command_executor.execute(driver_command, params)
  File "/Users/danmichael/.pyenv/versions/3.5.1/lib/python3.5/site-packages/selenium/webdriver/remote/remote_connection.py", line 464, in execute
    return self._request(command_info[0], url, body=data)
  File "/Users/danmichael/.pyenv/versions/3.5.1/lib/python3.5/site-packages/selenium/webdriver/remote/remote_connection.py", line 488, in _request
    resp = self._conn.getresponse()
  File "/Users/danmichael/.pyenv/versions/3.5.1/lib/python3.5/http/client.py", line 1174, in getresponse
    response.begin()
  File "/Users/danmichael/.pyenv/versions/3.5.1/lib/python3.5/http/client.py", line 282, in begin
    version, status, reason = self._read_status()
  File "/Users/danmichael/.pyenv/versions/3.5.1/lib/python3.5/http/client.py", line 243, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "/Users/danmichael/.pyenv/versions/3.5.1/lib/python3.5/socket.py", line 575, in readinto
    return self._sock.recv_into(b)
KeyboardInterrupt

geckodriver update causes slipsomat to bail

Summary: yesterday everything was still working, today it's not. In between of course I did the usual "nothing": geckodriver got updated from 0.14.0 to 0.15.0.

At startup, a firefox window gets opened but not addressed. Once the window is open, slipsomat bails:

Traceback (most recent call last):
  File "/usr/local/bin/slipsomat", line 11, in <module>
    load_entry_point('slipsomat==0.1.0', 'console_scripts', 'slipsomat')()
  File "build/bdist.macosx-10.11-x86_64/egg/slipsomat/slipsomat.py", line 765, in main
  File "build/bdist.macosx-10.11-x86_64/egg/slipsomat/slipsomat.py", line 70, in __init__
  File "build/bdist.macosx-10.11-x86_64/egg/slipsomat/slipsomat.py", line 152, in connect
  File "build/bdist.macosx-10.11-x86_64/egg/slipsomat/slipsomat.py", line 130, in get_driver
  File "/usr/local/lib/python2.7/site-packages/selenium-3.0.2-py2.7.egg/selenium/webdriver/firefox/webdriver.py", line 150, in __init__
    keep_alive=True)
  File "/usr/local/lib/python2.7/site-packages/selenium-3.0.2-py2.7.egg/selenium/webdriver/remote/webdriver.py", line 92, in __init__
    self.start_session(desired_capabilities, browser_profile)
  File "/usr/local/lib/python2.7/site-packages/selenium-3.0.2-py2.7.egg/selenium/webdriver/remote/webdriver.py", line 180, in start_session
    self.session_id = response['sessionId']
KeyError: 'sessionId'

Here's the geckodriver.log:

1489502198399	geckodriver	INFO	Listening on 127.0.0.1:49576
1489502199560	mozprofile::profile	INFO	Using profile path /var/folders/sm/zs2yrj5n3839gr87qgxlbtgr0000gp/T/rust_mozprofile.xJ1Zx6cBEzpl
1489502199564	geckodriver::marionette	INFO	Starting browser /Applications/Firefox.app/Contents/MacOS/firefox-bin with args []
1489502199593	geckodriver::marionette	INFO	Connecting to Marionette on localhost:49585
1489502200837	Marionette	INFO	Listening on port 49585

Any ideas? I guess I'll try reverting to the previous geckodriver and see if that unbreaks things.

Tatjana

Shell library

We should use a readline library. Maybe Pythons Cmd class?

Track changes in default letters

We need to track changes in the default letters. First plan was to use a different branch, but I think we have diverged so much from the default in some cases (e.g. by removing tables) that we cannot rely on regularly merging in changes, but rather will have to track the changes and do modifications as needed. We can keep the default letters in a separate folder and use some standard commit message for updates to the default letters.

The script to fetch the original letters will have to be slightly different, so we need a new command like pull default(?)

Interactive console (keep browser open)

Could save some time if we didn't have to go through login each time we want to push. Could be nice to have an interactive mode python slipsomat.py interactive with a prompt where you could just type push to push or something like that.

Startup timeout on SAML login

So I've been trying Chrome...
The sandbox is using a password-based login (auth_type=Alma) and starts up successfully.
The production environment is using SAML, and goes belly-up with a timeout:

Opening instance ...
Logging in as ...
Traceback (most recent call last):
  File "/usr/local/bin/slipsomat", line 11, in <module>
    load_entry_point('slipsomat==0.1.0', 'console_scripts', 'slipsomat')()
  File "build/bdist.macosx-10.11-x86_64/egg/slipsomat/slipsomat.py", line 829, in main
  File "build/bdist.macosx-10.11-x86_64/egg/slipsomat/slipsomat.py", line 168, in connect
  File "/usr/local/lib/python2.7/site-packages/selenium/webdriver/support/wait.py", line 80, in until
    raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message:

In a fit, I've tried to "just double all those timeouts, whatever they may be good for", and I was able to complete the SAML login up to the functioning Alma interface, but it only took longer to die...

The SAML timeout used to be tight (using firefox while it was still working for me), and requied fast typing; but since the login has already happened when slipsomat dies, I don't think that's the issue here.

Hide pickup number when no pickup date is provided

Just found that we're sending out SMS-es like this:

Klar til henting ved  .    
Hentenummer: -562.

{Document title}

Hentefrist: .

I think we've fixed this in the email letter, but not in the sms variant..

Pickup location is sometimes missing

Affected

Steps

  • Go to Receiving items
  • Select 'External identifer', check 'automatically notify patron', select 'Physical non-returnable', enter 'external identifier' and check 'complete the request'.
  • A message is sent to the requester that the document can be picked up, but the pickup location is missing because notification_data/request/assigned_unit_name is blank.

Note

The xml letters also contains a promising-looking field called pickup_location_str, but this is always blank. When asking about it on the Developer Network forum, I got the reply:

pickup_location_str is a transient field that was not meant to be part of the letter.
You should not use it, and we should remove it from the letter to avoid confusion.

Remove unsupported font tags

The code is currently cluttered with lots of font tags like

<font color="#666666">@@external_id@@:</font>

Since these aren't supported by html2ps, we might as well remove them?

watch command

In addition to push and pull, we could add watch, using something like watchdog to watch changes, and push a letter automatically if it's valid xml and if there's isn't a risk of overwriting remote changes (remote checksum matches the value in status.json).

ExLibris enforces selection of Circulation Desk - breaks Configuration Menu

For our instances, after logging in, staff have to manually select the circulation desk they're using for that session. (independently of their actual workplace):

select-cd

Until recently, it didn't have any adverse effect on configuration in general if that step was skipped - especially the configuration menu didn't really require selecting the (uneccessary, in that context) circulation desk and worked "anyway".

A user logging in manually is hindered by the pop-up to select the underlying elements of the Alma home screen and has to select a circulation desk. Selenium however happily ignores the intrusive pop-up and proceeds anyway.

As of lately in both Production and Sandbox, this benign behaviour of Alma is no longer the case. If there is no circulation desk selected, the configuration menu is displayed empty:

conf-empty

Slipsomat -which now would rather proceed directly to the configuration menu- gets rather unhappy about this, and bails.

Starting slipsomat 0.2.4
Connecting to sandbox02-eu:49KOBV_HUB
Logging in as ... DONE
Reading table... Traceback (most recent call last):
  File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/slipsomat/slipsomat.py", line 226, in open
    self.worker.first(By.CSS_SELECTOR, '#TABLE_DATA_fileList')
  File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/slipsomat/worker.py", line 43, in first
    return self.driver.find_element(by, by_value)
  File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 957, in find_element
    'value': value})['value']
  File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 314, in execute
    self.error_handler.check_response(response)
  File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: #TABLE_DATA_fileList


During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/bin/slipsomat", line 11, in <module>
    sys.exit(main())
  File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/slipsomat/shell.py", line 196, in main
    shell = Shell()
  File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/slipsomat/shell.py", line 54, in __init__
    self.table = TemplateConfigurationTable(self.worker)
  File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/slipsomat/slipsomat.py", line 221, in __init__
    self.open()
  File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/slipsomat/slipsomat.py", line 234, in open
    self.worker.click(By.XPATH, '//*[@href="#CONF_MENU6"]')
  File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/slipsomat/worker.py", line 63, in click
    element = self.wait.until(EC.element_to_be_clickable((by, by_value)))
  File "/Volumes/Users/theuser/.pyenv/versions/3.6.4/lib/python3.6/site-packages/selenium/webdriver/support/wait.py", line 80, in until
    raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message: 

Following the new python/selenium for beginners mini-tutorial (and a big thanks for that help!)
I got it to stop at the selection screen after worker.connect().

Would it be possible to add either a default circulation desk to slipsomat.cfg, or use the first element of the history as default?

<div class="marSidesAuto panel panel-default section  "><div id="FORM_LABEL_idCollapseTagUXP_924" class="panel-heading jsHideInIframePopup marbottom5"><div class="panel-title"><div class="entityAudit alignRight"></div><a title="" class="btn btn-secondary border0 collapsible" role="button" data-toggle="collapse" href="#idCollapseTagUXP_924" aria-controls="idCollapseTagUXP_924" aria-expanded="true"><span class="alignRight glyphicon glyphicon-menu-right"></span><span class="sectionTitle">Please choose your current desk/department</span></a></div></div><div id="idCollapseTagUXP_924" class="panel-collapse collapse in" role="tabpanel"><div class="panel-body"><!--  ERRORS  -->
	<script>
		function selectInstitution(newInst) {//open link in same window or differnt tab/window based on customer parameter
			

    		var condition="";
    		if(condition=="window"){
    			 var features = "width="+$(window).width()+",height="+ $(window).height()+",menubar=1, toolbar=1";
    			window.open(newInst, "window2", features);
    		}else if(condition=="tab"){
    			window.open(newInst);
    		}else{
    			location.href=newInst;
    		}

		}
		function changeInstitutionFromSelect(){
			selectInstitution($('#pageBeanselectedInst').val());

		}
		</script>

<div id="availableUnits" class="">
									<div class="form row"><div class="col  col-md-12 col-xs-12  wide-field-1 marbottom5 ">
<div class="row ">
<label class="col col-md-3 col-xs-2 control-label height34 displayTable lineHeight35 padSides5 fontReg textRight" for="pageBeanselectedLocation"><span class="displayTableCell verticalMiddle lineHeight16">I am physically at:</span><span class="dummySpace">&nbsp;</span></label>
<div class="col col-md-8 col-xs-10 form-field  leftMarginA">
<div class="input-group ui-combobox"><input id="pageBeanselectedLocation" class="form-control ui-combobox-input ui-autocomplete-input ui-widget ui-widget-content jsComboPlaceholder defaultPlaceholderDiv jsRemoveOnInit jsLazyInit" value="None of these"><span class="input-group-btn jsRemoveOnInit "><button aria-label="Option list toggle" type="button" class="jsLazyInit btn btn-secondary dropdown-toggle height34 jsComboPlaceholder defaultPlaceholderButton"><span class="caret"></span></button></span><select  data-save-sh="true"  name="pageBean.selectedLocation" id="pageBeanselectedLocation_hiddenSelect"  class="jsDummy jsCombobox jsAddHideClass "  title="Select an item from the list. Use autocomplete to view fewer options. Press ESC to reset." >
<option  class=" jsKeepBottom "  value="Null"  >None of these</option>
<option  value="121"  >Digitization Department For Institution</option>
<option  value="1713420350002882"  >long list edited short</option>
<option  value="395021420002882"  >sublibrary-cd-xxx</option>
<option  value="1713420410002882"  >sublibrary-cd-xxx</option>
<option  class="selectionHistoryItem"  value="395017700002882"  >sublibrary-cd-xxx</option>
<option  class="selectionHistoryItem"  value="1713419540002882"  >sublibrary-cd-xxx</option>
</select>
</div><div id="pageBeanselectedLocation_invalid_error" class=" hide alert alert-danger jsToolTip ">The phrase didn't match any value.</div></div>
</div>
</div>
</div>

I tried to select one of the circulation desks:

find_element_by_xpath("//select[@id='pageBeanselectedLocation']/option[@value='395017700002882']").click()

but my hybris was promptly regarded with a number of errors I'm currently trying to learn my way out of.

Add information about required columns in Almas table view

We had an issue today with the script where one of our staff had changed their default columns in the table view causing the script to crash, specifically the person had hid the "Updated by" column which slipsomat uses during push.

We think there should be some information in the setup part of the readme. Either about exactly which columns are needed or that the user should reset their columns to default.

Hentebeskjed-issue, SMS, artikkelkopi

Hei, melde inn en liten ting:
Hentebeskjed på SMS, på artikkelkopi fra innlånstjenesten vår, har hentenummer (uten dato, men med løpenummer: " -20871" eller noe sånt).
Jeg så dette på låners telefon.
Men eposten (i Attachments) ser bra ut (altså uten hentenummer).
Mulig dette er gjennomgående, men at vi ikke har sett det tidligere, fordi det bare gjelder SMS og ikke epost?

Borrowing request: 47bibsysubo0005722
Hentebeskjedene sendt 13/5.

Øystein

Hentebeskjed: Uklart hva som er hentested

Eksempel fra @knuthe : Bok som er bestilt fra Informatikkbiblioteket, men som skal hentes i Vilhelm Bjerknes’ hus:

hentebeskjed

To forbedringsforslag:

_1. Erstatte «Utlånet Ureal» med «Vilhelm Bjerknes’ hus»:_

@superLine @GeirNordanger @kurosay , noe dere kan fikse i konfigurasjon?

_2. Knytte kontakt-adresse og avsender til hentested, ikke til eierbibliotek:_

Festlig nok mangler kontaktadresse for hentested rett og slett i XML-en som genererer eposten.. Men vi har ihvertfall navn på hentested («UiO Realfagsbiblioteket – Utlånet Ureal» altså..), så det kan forsåvidt legges under "Vennlig hilsen,"

Option to work with sandbox?

Hi,

Thanks for this fantastic tool. Was looking for some help on how to handle Alma letters in Git, but this was much more than I would have hoped for.

But I struggle to use the tool with our (premium) sandbox in parallell to the production environment. Do you have any workflow in place for this?

So far I've been trying to move slipsomat.cfg and status.json around to work with one at a time, but got stuck when somehow the status.json got out of sync with the actual content in the sandbox, so I have to manually confirm every file. Another option would probably be to have two separate working copies where one is configured to work with the sandbox. But I would need to protect status.json from being updated from the sandbox copy.

Do you work with this tool with the sandbox, and if so, how?

Add strings

Need to add support for pulling/pushing the translatable strings as well

Pip installing an old version ?

Hello,
trying to install slipsomat using instrucintions from the readme (pip install -U slipsomat) I can see that the version installed is 0.2.4 when according to what I can see in the files there has been two versions meanwhile.
As I have a timeout I suspect it might be because of the version I use, would it be possible to push the 0.2.6 version to pip?

Ingen stikksedel ved retur av fjernlån

Meldt Bibsys via Geir "Stikksedler - retur av fjernlån" 12.05.2016, 08.18

Det ser ikke ut som om det genereres noe brev i det heletatt når man tar retur av innlånte bøker.

Det er mye ekstraarbeid i skrankene og blir oftere feil når vi må søke opp hvor boka skal+skrive libnr på en lapp.

Med mindre det er noe vi har misforstått ville det vært fint om dere tok dette opp videre med ExLibris.

Ukjent ticket no

Plans for working with the new interface in Alma?

With the August release Ex Libris introduced an improved interface to letter customization (and "component customization"), where the labels and template for a letter are accessed in tabs on the same page. According to the release notes the old pages will be replaced in the near future.

While the new pages probably are better from a user perspective, they also seem harder to script as the complete list of letters is no longer accessible from a single page, and at least I can't find information on when a template was last updated.

Do you plan to continue development of slipsomat to work with the new pages?

Add patron name to transit slip

We need some patron information on the transit slips. This will also help in figuring out books that arrive unexpectedly.

Kvittering for utlån

Oppsummerer epostutveksling:

@ewinge :

Vi skulle gjerne hatt mulighet for å skrive ut kvitteringer for lån fra alma, feks for bruk som adresselapp. Er det noe dere har drøftet?

@GeirNordanger :

Foreslår at du og Anne Gunn tester. For å skru på for en skranke: fulfillment configuration -> you are configuring -> biblioteket du vi teste med -> cirkulation desk -> default-> printing information

slipsomat bailing out on firefox startup

As of last week, slipsomat barfed when set upon our sandbox. The production environment was still able to start, so with little time at my hands I ignored the somnolent dragon and crossed my fingers.
Of course, another weekend happened, and on Tuesday the production environment displayed the same nausea...
So, as of this week, something seems to be broken.

  File "/usr/local/bin/slipsomat", line 11, in <module>
    load_entry_point('slipsomat==0.1.0', 'console_scripts', 'slipsomat')()
  File "build/bdist.macosx-10.11-x86_64/egg/slipsomat/slipsomat.py", line 831, in main
  File "build/bdist.macosx-10.11-x86_64/egg/slipsomat/slipsomat.py", line 158, in connect
  File "build/bdist.macosx-10.11-x86_64/egg/slipsomat/slipsomat.py", line 134, in get_driver
  File "/usr/local/lib/python2.7/site-packages/selenium/webdriver/firefox/webdriver.py", line 155, in __init__
    keep_alive=True)
  File "/usr/local/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 92, in __init__
    self.start_session(desired_capabilities, browser_profile)
  File "/usr/local/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 183, in start_session
    self.capabilities = response['value']
KeyError: 'value'

So far I'm clueless. Just for giggles I tried with Firefox Versions 47.0, 49.0.1 and 53.0 (by setting firefox_path) to no avail.

push goes kaboom: unable to locate element

Both in production and sandbox, push complains about not finding element: [id="#ROW_ACTION_fileList_65_c.ui.table.btn.edit input"]. Similarily named items exist, but without "input" denominator (from page source, assuming I hit the right one):

<input class="jsCloseableContainerOpener" type="submit" name="All" id="input_fileList_65" value="Actions" onclick="return closeAllActions(this,'fileList',65)"/> </span>
  	<ul id="ROW_ACTION_fileList_65" class="comboActions underButton hide  jsCloseableContainer" >

		<li class="clearfix" id="ROW_ACTION_fileList_65_c.ui.table.btn.edit">
			<input title="" name="pageBean.pageInfoFinal.sectionses[2].sections[1].sectionLists[0].parameters.rowAction.linkActionFields[0].submitOperations[65].submitFlag"  onclick="storeSelectedRowId(this);this.form.target='_self';return loadPage(this);" type="submit" class="submitAsLink " value="Edit" /></li>
		<li class="clearfix" id="ROW_ACTION_fileList_65_c.ui.table.btn.restore">
			<input title="" name="pageBean.pageInfoFinal.sectionses[2].sections[1].sectionLists[0].parameters.rowAction.linkActionFields[4].submitOperations[65].submitFlag"  onclick="storeSelectedRowId(this);this.form.target='_self';return loadPage(this);" type="submit" class="submitAsLink " value="Restore" /></li>
		<li class="clearfix" id="ROW_ACTION_fileList_65_c.ui.table.btn.view_default">
			<input title="" name="pageBean.pageInfoFinal.sectionses[2].sections[1].sectionLists[0].parameters.rowAction.linkActionFields[5].submitOperations[65].submitFlag"  onclick="storeSelectedRowId(this);this.form.target='_self';return loadPage(this);" type="submit" class="submitAsLink " value="View&#x20;Default" /></li>
												</ul>											

The error in all its glory:

slipsomat> push
Reading table... DONE
The following 2 file(s) contains local modifications.
 - xsl/letters/FulTransitSlipLetter.xsl
 - xsl/letters/FulReasourceRequestSlipLetter.xsl
Push updates to Alma?  (y/N) y
- FulTransitSlipLetter.xsl                                    
Exception: Message: Unable to locate element: [id="#ROW_ACTION_fileList_65_c\.ui\.table\.btn\.edit input"]

Traceback (most recent call last):
  File "/Volumes/Users/theuser/.pyenv/versions/3.5.1/lib/python3.5/site-packages/slipsomat/slipsomat.py", line 808, in execute
    function(self.browser, *args)
  File "/Volumes/Users/theuser/.pyenv/versions/3.5.1/lib/python3.5/site-packages/slipsomat/slipsomat.py", line 667, in push
    if letter.push():
  File "/Volumes/Users/theuser/.pyenv/versions/3.5.1/lib/python3.5/site-packages/slipsomat/slipsomat.py", line 531, in push
    txtarea = self.edit()
  File "/Volumes/Users/theuser/.pyenv/versions/3.5.1/lib/python3.5/site-packages/slipsomat/slipsomat.py", line 389, in edit
    self.scroll_into_view_and_click(editBtnSelector)
  File "/Volumes/Users/theuser/.pyenv/versions/3.5.1/lib/python3.5/site-packages/slipsomat/slipsomat.py", line 325, in scroll_into_view_and_click
    element = self.table.browser.driver.find_element(by, value)
  File "/Volumes/Users/theuser/.pyenv/versions/3.5.1/lib/python3.5/site-packages/selenium-3.4.1-py3.5.egg/selenium/webdriver/remote/webdriver.py", line 787, in find_element
    'value': value})['value']
  File "/Volumes/Users/theuser/.pyenv/versions/3.5.1/lib/python3.5/site-packages/selenium-3.4.1-py3.5.egg/selenium/webdriver/remote/webdriver.py", line 252, in execute
    self.error_handler.check_response(response)
  File "/Volumes/Users/theuser/.pyenv/versions/3.5.1/lib/python3.5/site-packages/selenium-3.4.1-py3.5.egg/selenium/webdriver/remote/errorhandler.py", line 194, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: [id="#ROW_ACTION_fileList_65_c\.ui\.table\.btn\.edit input"]

[?] Now what?: 
 > Restart browser

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.