<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://verbovetskaya.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://verbovetskaya.com/" rel="alternate" type="text/html" /><updated>2026-03-12T18:43:58+00:00</updated><id>https://verbovetskaya.com/feed.xml</id><title type="html">Alevtina Verbovetskaya</title><subtitle>Librarian, knitter, vegan.</subtitle><author><name>Alevtina Verbovetskaya</name></author><entry><title type="html">Counting to ten</title><link href="https://verbovetskaya.com/blog/counting-to-ten/" rel="alternate" type="text/html" title="Counting to ten" /><published>2026-03-02T00:00:00+00:00</published><updated>2026-03-02T00:00:00+00:00</updated><id>https://verbovetskaya.com/blog/counting-to-ten</id><content type="html" xml:base="https://verbovetskaya.com/blog/counting-to-ten/"><![CDATA[<p>A few weeks ago, I told Stephen he was moving too fast—not through the material, but through the pauses. He’d ask something thoughtful, then fill the quiet before anyone had time to think. It’s a reflex most of us have.</p>

<p>So he started counting to ten.</p>

<p>I do this myself in almost every meeting I lead. When I ask for questions, I pause and count. Most times, someone speaks up. It feels awkward every single time, and it works almost every single time.</p>

<p>This week, Stephen went past ten and was about to give up. He even messaged me privately: <em>ah well</em>.</p>

<p>The question he’d asked was whether their participation in this program had changed how people thought about AI’s impact on the profession. He’d just demoed a reference agent he built for the Graduate Center—it pulls from LibGuides and the Primo API, and in his tests it outperforms the current chat service. He hasn’t deployed it. He’s still thinking carefully about what it means for an AI agent to be someone’s first interaction with the library.</p>

<p>Then Will started talking. He’s in library school and new to the profession and these AI tools, and he was honest about feeling genuinely unsettled. He could see how well AI handles reference questions so that wasn’t really the issue. What gave him pause was what that efficiency means for the person on the other end. The relationships, the friction, the slow work of getting curious about something—are we moving toward or away from those? “What actually is the point?” he asked. And then, almost in the same breath: it’s also really cool to learn how this works.</p>

<p>The rest of the room had a lot of feelings. Robin talked about technology and humanity in the long view, neither doomer nor booster. Jason reframed it as an information literacy question. Ashley raised the political stakes—what are our obligations as librarians when the tools we’re using are developed by companies making decisions we don’t control? Shamiana said she doesn’t fear AI going away; she worries more about access eventually becoming limited to certain groups.</p>

<p>Nobody rushed to resolve any of it, which felt right.</p>]]></content><author><name>Alevtina Verbovetskaya</name></author><category term="leadership" /><category term="artificial-intelligence" /><summary type="html"><![CDATA[Six weeks into our agentic AI peer mentoring cohort, Stephen asked whether any of this had changed people's minds. Then he waited.]]></summary></entry><entry><title type="html">An AI cohort for librarians</title><link href="https://verbovetskaya.com/blog/ai-cohort-for-librarians/" rel="alternate" type="text/html" title="An AI cohort for librarians" /><published>2026-02-18T00:00:00+00:00</published><updated>2026-02-18T00:00:00+00:00</updated><id>https://verbovetskaya.com/blog/ai-cohort-for-librarians</id><content type="html" xml:base="https://verbovetskaya.com/blog/ai-cohort-for-librarians/"><![CDATA[<p>Last semester, a colleague of mine at the CUNY Graduate Center started showing up to conversations with a lot of energy about AI. Stephen Zweibel, Digital Scholarship Librarian, had been making the case that librarians needed to get serious about it—not in the “here’s how to use ChatGPT for your reference questions” way, but in the “we should actually be building things” way. It’s a different argument than the ones that tend to dominate at a large university, where the AI conversation mostly revolves around faculty research support, plagiarism policy, and enrollment tools. Workflow automation, in-house tool development, reducing vendor dependency—that stuff doesn’t always have a natural home. My boss and I started thinking about how to channel Stephen’s enthusiasm into something structured. A peer mentoring cohort seemed like the right fit.</p>

<p>We’re three weeks into a 16-week program exploring agentic AI and its implications for library work, and I’ve been trying to write something about it before too much time passes and I lose the early impressions.</p>

<p>The cohort builds on something we’ve been doing for a few years through our Alma Extensibility Task Force, a group of CUNY librarians who use Alma’s REST APIs to extend functionality based on systemwide needs. That work has produced small but meaningful things: automations, integrations, configuration improvements that Alma doesn’t natively support. The idea here is to expand that model beyond people who already identify as programmers, and beyond Alma itself.</p>

<p>Thirteen library faculty and staff from nine CUNY campuses are spending the semester building AI-enabled tools to address real workflow challenges. Stephen is leading the cohort, guiding participants through development while keeping a consistent focus on critical evaluation: understanding APIs, interrogating model limitations, assessing risk, and figuring out what’s actually technically feasible versus what’s well-marketed.</p>

<p>The projects reflect the kinds of problems libraries are genuinely grappling with: automating faculty publication tracking for institutional repositories, building accessibility checkers for course content, enhancing discovery systems, streamlining course reserves workflows, developing CUNY-wide tools for data access. People’s technical backgrounds range from complete beginners to experienced developers, which makes the dynamic interesting.</p>

<p>A few of the projects I’ve been wanting to pursue for a while—including externalizing Alma letters into version-controlled infrastructure and standardizing access model descriptions across institution zones—are taking shape within this cohort. These were ideas that had been sitting on a back burner for longer than I’d like to admit. With structured time and tools like Claude Code, they’ve started moving.</p>

<p>My role is mostly scaffolding: structuring the cohort, handling logistics, setting up the shared collaboration space in Microsoft Teams, trying to create conditions where people can experiment without feeling overwhelmed. The Teams space is already more active than I expected: participants troubleshooting installation issues together, sharing resources, asking questions about APIs and workflow automation. Several people are juggling a lot right now, professionally and personally, and they’re still showing up.</p>

<p>We’re only three weeks in, but it’s already interesting to watch.</p>]]></content><author><name>Alevtina Verbovetskaya</name></author><category term="leadership" /><category term="artificial-intelligence" /><summary type="html"><![CDATA[Three weeks into a 16-week peer mentoring cohort, and we're already building things I'd been wanting to build for years.]]></summary></entry><entry><title type="html">Before the updates go live</title><link href="https://verbovetskaya.com/blog/before-the-updates-go-live/" rel="alternate" type="text/html" title="Before the updates go live" /><published>2025-08-02T19:16:00+00:00</published><updated>2025-08-02T20:36:00+00:00</updated><id>https://verbovetskaya.com/blog/before-the-updates-go-live</id><content type="html" xml:base="https://verbovetskaya.com/blog/before-the-updates-go-live/"><![CDATA[<p>For a long time, my team read release notes the way I imagine most people do: quickly, right before a meeting, and with mild dread.</p>

<p>Every quarter we would review the Alma and Primo VE updates and then repeat the same conversation six different times—once with each of our three working groups and again with our three advisory committees. We’d speculate about what a feature probably did based on screenshots. We’d guess which workflows it might affect. And most of that context never made it beyond the committee representative.</p>

<p>It wasn’t very efficient, and it wasn’t particularly engaging. More importantly, it wasn’t helping the staff across our 30+ libraries feel ready for change.</p>

<p>So in late 2024, we tried something different.</p>

<p>Instead of discussing the release notes in six separate meetings, we started hosting a single open webinar for all CUNY library staff. We call it <em>Shelf Help</em>, and we schedule it the Thursday before Ex Libris pushes updates to production. The timing matters: people get a chance to understand what’s coming before the changes land.</p>

<p>The format wasn’t the only thing that changed, though. The bigger shift was how we prepared.</p>

<p>Rather than summarizing the release notes, we started testing them.</p>

<p>Before each session, we read through the release notes line by line and try the new features in our Alma and Primo VE sandboxes. We decide which changes are actually relevant to our campuses, build examples and walkthroughs, and then share the recording and documentation afterward so people can revisit it later.</p>

<p>Instead of saying, “Here’s what the notes say,” we can say, “Here’s what this does in our environment, and here’s what to watch for.”</p>

<p>We launched the first session in November 2024. A year and four sessions later, we typically see around 70 registrants with roughly 80% attendance. After that first session, we sent out a short survey: 89% of respondents rated their satisfaction as high, and 100% said they wanted the series to continue.</p>

<p>The comments were encouraging:</p>

<blockquote>
  <p>“Reading a long list of release notes is overwhelming. The format chosen made the information much more accessible and understandable.”</p>
</blockquote>

<blockquote>
  <p>“I really appreciated seeing updates outside my functional area; they still impact the staff that I supervise.”</p>
</blockquote>

<blockquote>
  <p>“I love Shelf Help! I know it takes a lot for the three of you to prepare. I’m grateful.”</p>
</blockquote>

<p>It <em>does</em> take time to prepare each session. But it saves far more time across the system. And just as importantly, it reduces anxiety. No one enjoys logging in one morning to a changed interface and a flood of “What the heck happened?” emails.</p>

<p>What this experience has reminded me is that support doesn’t always mean creating something brand new. Sometimes it means taking something dense and scattered—like release notes—and turning it into something shared, practical, and easier to navigate together.</p>]]></content><author><name>Alevtina Verbovetskaya</name></author><category term="leadership" /><category term="library-systems" /><category term="alma" /><category term="primo-ve" /><category term="change-management" /><summary type="html"><![CDATA[We used to read release notes the way most people do: quickly, right before a meeting, and with mild dread. Then we tried something different.]]></summary></entry><entry><title type="html">One hour a day</title><link href="https://verbovetskaya.com/blog/one-hour-a-day/" rel="alternate" type="text/html" title="One hour a day" /><published>2024-06-14T19:01:00+00:00</published><updated>2024-06-14T19:14:00+00:00</updated><id>https://verbovetskaya.com/blog/one-hour-a-day</id><content type="html" xml:base="https://verbovetskaya.com/blog/one-hour-a-day/"><![CDATA[<p>A few years ago, work felt chaotic. We had just migrated to Ex Libris’s Alma in the middle of a pandemic. We’d gone through multiple interim Deans. Several people had retired or resigned in the department. I had become Director of the unit I’d been a member of for eight years—a job I’d received no training for and one I had to do while working remotely. And I was onboarding a new staff member.</p>

<p>It was… a lot. Especially all at once.</p>

<p>I had been the last new hire in the unit and, as I said, I’d already been there for eight years. I spent a lot of time working on onboarding documentation, trying to make sure I’d covered all the bases.</p>

<p>But when my new teammate started, I quickly realized I’d taken for granted the relationships I already had with my colleagues—relationships built over years of in-person work.</p>

<p>This new hire? She was brand new to my team, brand new to the university, and brand new to New York City.</p>

<p>It was a lot for her, too.</p>

<p>On the advice of my life partner—who works in tech and had been working remotely for years, long before the pandemic—I decided to try a daily co-working hour on Zoom. It’s a time when anyone on the team can show up for questions, work chat, brainstorming, or just to work alongside each other.</p>

<p>It’s not quite a meeting but, in the beginning, it sure felt like one. It was awkward and stiff. None of us knew what to do or how to act. Were we supposed to talk? Stay silent? Look busy?</p>

<p>But persistence paid off. Though I stressed that attendance was optional, I vowed to show up every day. Slowly but surely, we figured it out and settled into a rhythm. People opened up. We reviewed support tickets together. We supported each other through losses. We read through release notes. We laughed. Some days we worked in silence for half an hour, and that was fine, too.</p>

<p>This shared space is now how we start every day. It’s when the whole team gets together—sharing progress, swapping tips, troubleshooting problems, and usually making each other laugh. It sets the tone for the rest of the day. Attendance is still optional, but everyone shows up.</p>]]></content><author><name>Alevtina Verbovetskaya</name></author><category term="management" /><category term="leadership" /><category term="remote-work" /><category term="change-management" /><summary type="html"><![CDATA[On the advice of my partner, I started an optional daily co-working hour for my team. That was three years ago. Everyone still shows up.]]></summary></entry><entry><title type="html">Life with Pi: Microcomputing in Academia</title><link href="https://verbovetskaya.com/blog/life-with-pi-microcomputing-in-academia/" rel="alternate" type="text/html" title="Life with Pi: Microcomputing in Academia" /><published>2013-12-09T00:00:00+00:00</published><updated>2023-04-08T00:00:00+00:00</updated><id>https://verbovetskaya.com/blog/life-with-pi-microcomputing-in-academia</id><content type="html" xml:base="https://verbovetskaya.com/blog/life-with-pi-microcomputing-in-academia/"><![CDATA[<p>Last Friday, I co-led a presentation on single-board computers at the <a href="http://www.centerdigitaled.com/events/CUNY-IT-Conference-2013.html">2013 CUNY IT Conference</a>. Since it was a very well-attended session (where we had great discussions with the attendees), I thought I’d provide a brief recap and link to the presentation material.</p>

<h3 id="life-with-pi-microcomputing-in-academia">Life with Pi: Microcomputing in Academia</h3>

<p><img src="/assets/img/life_with_pi_-_microcomputing_in_academia.png" alt="Life with Pi: Microcomputing in Academia" /></p>

<h4 id="introduction-to-single-board-computers">Introduction to single-board computers</h4>

<p><a href="http://www.verbovetskaya.com/">Allie Verbovetskaya</a>, Web &amp; Mobile Systems Librarian / CUNY</p>

<p>Before we began with the “formal” presentation, I showed a brief video:</p>

<iframe src="//player.vimeo.com/video/55658574?title=0&amp;byline=0&amp;portrait=0&amp;color=ffffff" width="800" height="450" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>

<p>Once the audience was thoroughly confused, I explained that the <a href="http://scott.j38.net/interactive/beetbox/">BeetBox</a> is a quite literal “beatbox” that uses beets as percussion instruments. To achieve this, there are touch sensors in the beets that are wired to a Raspberry Pi. To emit the drum sounds, there is an amplifier and a speaker also hooked up to the RPi. There is a Python program that’s running on the RPi and translating the touches into drum samples. The RPi powers this apparatus behind-the-scenes.</p>

<p>But what is a Raspberry Pi? It is a type of microcomputer. So what’s a microcomputer? It’s a single-board computer that’s small, cheap, and open source. It’s about the size of a credit card and varies in price from $25 up to $100. As such, it’s quite an affordable little machine, containing all the parts of a functional computer: microprocessor, RAM, I/O, power supply, and so on.</p>

<p>The most popular microcomputer—at the moment, anyway—is the <a href="http://www.raspberrypi.org/">Raspberry Pi</a>. It’s $25 for the base model and $35 for the “souped up” version (with more RAM and ports). Another one that comes up frequently is the <a href="http://beagleboard.org/Products/BeagleBone">BeagleBone</a> (brought to you by <a href="http://www.ti.com/">Texas Instruments</a>, the calculator guys) and it’s quite a bit more expensive at $89. And, the one that’s been around the longest, is the <a href="http://www.arduino.cc/">Arduino</a>. They have several boards but the Uno board costs $30.</p>

<p>So now that we understand what they are… what are they for? Well, they can be used for hobbies, such as <a href="http://learn.adafruit.com/retro-gaming-with-raspberry-pi">building a retro arcade gaming station</a> or <a href="http://brewpi.com/">home brewing</a>. Or they can be used to solve specific problems, such as the <a href="http://www.instructables.com/id/RFID-pet-feeder/">RFID pet feeder</a> which was created by someone who needed to feed one of his cats a medicated food and, therefore, could not have his two cats eating each other’s food. (What the creator did was program an Arduino to move the lid on the appropriate food dish based on the cat that approaches the feeding station. This is done via RFID chips that have been attached to the cats’ collars. That way, when Sick Cat approaches the feeding area, her food is made available to her. When she walks away, the lid slides back over so no one cat eat. Then, when Healthy Cat gets hungry, the lid covering her food opens so she can eat. And so on.) Another use is for data collection, such as the <a href="http://www.botanicalls.com/">Botanicalls kit</a> which allows a user to measure a plant’s comfort levels (moisture in the soil, amount of sunlight, etc.) and tweet “status updates” so you can tell when your plant is thirsty or too hot. (It will also respond to changes in its status, so if it’s thirsty and you watered it, it’ll submit a tweet of thanks.)</p>

<p>So you can begin to see how microcomputers can be used for more than basic tinkering. But you may also be thinking: “That’s great but I’m not a programmer!” And that’s OK! You don’t have to be. Because these microcomputers are open source, there are large and dedicated communities surrounding each. There are plenty of tutorials and guides online—as well as complete projects!—that you can use to get started. You can also seek help from many places, including:</p>

<ul>
  <li><a href="http://www.adafruit.com/">http://www.adafruit.com/</a></li>
  <li><a href="http://www.makezine.com/">http://www.makezine.com/</a></li>
  <li><a href="http://www.themagpi.com/">http://www.themagpi.com/</a></li>
  <li><a href="http://www.element14.com/">http://www.element14.com/</a></li>
  <li><a href="http://raspberrypi.stackexchange.com/">http://raspberrypi.stackexchange.com/</a></li>
</ul>

<p>But why should you bother to do any of this? Well, there are actually uses beyond recreation. In fact, there is evidence of more and more applications in academia. My colleague Junior discussed uses in the classroom while Robin explained how microcomputers can be used in and for research. Steve discussed the benefits of teaching microcomputing techniques and explain why computational literacy is becoming more important in today’s world. The presentation was then rounded out with demonstrations of projects that each of us had constructed, followed by questions from the audience.</p>

<h4 id="uses-in-pedagogy">Uses in pedagogy</h4>

<p><a href="http://www.juniortidal.com/">Junior Tidal</a>, Web Services &amp; Multimedia Librarian / NYCCT</p>

<p>Junior discussed uses of microcomputers in the classroom, including:</p>

<ul>
  <li>Individual research stations</li>
  <li>Cross-disciplinary projects</li>
  <li>Testing environment for coding projects</li>
  <li>Class/course web server per class/student for ad hoc storage or collaboration</li>
  <li>Paperless archive repository for classes</li>
</ul>

<p>You can also see Junior’s write-up of our presentation for more information about his section: <a href="http://juniortidal.com/2013/12/life-of-pi/">http://juniortidal.com/2013/12/life-of-pi/</a>.</p>

<h4 id="uses-in-research">Uses in research</h4>

<p><a href="http://www.robincamille.com/">Robin Davis</a>, Emerging Technologies &amp; Distance Services Librarian / John Jay College</p>

<p>Robin opened with several real-life examples of microcomputers currently being used for research purposes. She then outlined other venues for using single-board computers in and for research:</p>

<ul>
  <li>Cheap, disposable computing in the lab or studio</li>
  <li>Use inexpensive sensors (e.g., temperature, motion, light, GPS, acceleration, etc.)</li>
  <li>Build prototypes quickly</li>
  <li>Maintain tight control over your machine(s)</li>
  <li>Topic of publication (both scholarly and popular)</li>
</ul>

<p>For a complete overview of Robin’s contribution to the presentation, see the write-up on her website: <a href="http://www.robincamille.com/presentations/microcomputing/">http://www.robincamille.com/presentations/microcomputing/</a>.</p>

<h4 id="computational-literacy">Computational literacy</h4>

<p><a href="http://www.zweibel.org/">Stephen Zweibel</a>, Visiting Lecturer (Librarian) / Hunter College</p>

<p>Steve discussed the importance of computational literacy and how microcomputers can be used to teach this literacy to the next generation of learners. He defined “computational literacy” as the ability to use computers and computational technologies to solve problems, and explained how it supports algorithmic thinking and collaboration.</p>

<h4 id="demonstrations">Demonstrations</h4>

<ul>
  <li>I discussed setting up a personal Dropbox-clone using an <a href="http://www.owncloud.com/">ownCloud</a> instance on a Raspberry Pi-powered web server, to be used as a classroom repository or just a safe place to store potentially sensitive materials.</li>
  <li>Junior demonstrated his “auto-citation” project. Using the <a href="https://openlibrary.org/developers/api">Open Library API</a>, he created a script that makes it possible to scan an ISBN (or enter it manually) and get a citation (in APA, MLA, and Chicago styles) in return.</li>
  <li>Robin showed a light level logger, wherein she used Python to read data submitted by a 95¢ photocell sensor wired on a breadboard (hooked up to a Raspberry Pi).</li>
  <li>Steve described the concept of a <a href="http://jasongriffey.net/librarybox/">LibraryBox</a> (digital file repository available via its own Wi-Fi signal) and encouraged the audience to connect to his LibraryBox network and download some documents to see his project in action.</li>
</ul>

<h3 id="presentation-material">Presentation Material</h3>

<p>The slides are available online: <a href="http://www.robincamille.com/jj/cunyit/">http://www.robincamille.com/jj/cunyit/</a>.</p>

<p>We also created a handout that was made available at the presentation. You can download it from <a href="http://www.robincamille.com/jj/cunyit/handout.pdf">http://www.robincamille.com/jj/cunyit/handout.pdf</a>.</p>

<h3 id="colophon">Colophon</h3>

<p>The four co-presenters worked on this presentation collaboratively using git and a shared repository on <a href="http://www.github.com/">GitHub</a>: <a href="https://github.com/szweibel/CUNY-IT-Presentation">https://github.com/szweibel/CUNY-IT-Presentation</a>. It was the first time any of us has used GitHub in this manner and it proved quite successful.</p>

<p>We used the <a href="https://github.com/hakimel/reveal.js/">reveal.js presentation framework</a> for our slides. It’s very easy to use and provides beautiful (and responsive!) slidedecks.</p>]]></content><author><name>Alevtina Verbovetskaya</name></author><category term="research" /><category term="raspberry-pi" /><category term="presentation" /><category term="technology" /><summary type="html"><![CDATA[At the 2013 CUNY IT Conference, we demonstrated how affordable single-board computers like Raspberry Pi can transform academia through creative projects ranging from RFID pet feeders to classroom web servers and research data collection.]]></summary></entry><entry><title type="html">Using Adobe Digital Editions on an Ubuntu desktop</title><link href="https://verbovetskaya.com/blog/using-adobe-digital-editions-on-an-ubuntu-desktop/" rel="alternate" type="text/html" title="Using Adobe Digital Editions on an Ubuntu desktop" /><published>2013-11-17T00:00:00+00:00</published><updated>2013-11-17T00:00:00+00:00</updated><id>https://verbovetskaya.com/blog/using-adobe-digital-editions-on-an-ubuntu-desktop</id><content type="html" xml:base="https://verbovetskaya.com/blog/using-adobe-digital-editions-on-an-ubuntu-desktop/"><![CDATA[<p><a href="https://acid-stars.com/2013/11/16/need-moar-tech/trackback/">I recently purchased a new laptop and installed the Ubuntu OS on it.</a> However, in my excitement to install a UNIX-like working environment, I forgot that some software works only with the two major operating systems (i.e., Windows and Mac). Namely, I needed to install <a href="http://www.adobe.com/products/digital-editions.html">Adobe Digital Editions</a> on my new machine and panicked briefly when I realized I couldn’t do that. But after some quick research, I learned how to install ADE and then have it recognize my e-reader.</p>

<ol>
  <li>
    <p>Open the Ubuntu Software Center and search for <a href="http://www.winehq.org/">Wine</a>. Install it.
<img src="/assets/img/ebook_software_center.png" alt="ebook_software_center" /></p>
  </li>
  <li>
    <p>From the dash, open Winetricks. Choose “install an app.” Select “adobe_diged” and hit OK.
<img src="/assets/img/ebook_winetricks_install_ade.png" alt="ebook_winetricks_install_ade" /></p>
  </li>
  <li>
    <p>Go through the installation steps. Agree to the EULA. Authorize the computer with your Adobe ID. Close ADE.
<img src="/assets/img/ebook_ade_authorize.png" alt="ebook_ade_authorize" /></p>
  </li>
  <li>
    <p>From the dash, open Winetricks. Choose “select adobe_diged (Adobe Digital Editions)” and then select “Run winecfg.” Under the “Drives” tab, create a new drive letter N (it auto-mounts elsewhere but does not keep changes), add directory <code class="language-plaintext highlighter-rouge">/media/nook/</code> (or the specific location of your Nook on your machine), and change type to “Floppy drive” (under advanced options).
<img src="/assets/img/ebook_winecfg_drives.png" alt="ebook_winecfg_drives" /></p>
  </li>
</ol>

<p>That’s it! You now have ADE 1.7.2 installed on your Ubuntu machine that can be accessed from the dash. Use it to download library e-books, authorize protected PDFs, move books to your Nook*, and so on.</p>

<p>* I’ve only tested this setup with a <a href="http://www.barnesandnoble.com/nook/">Nook</a> but I assume the same steps will work for all other ADE-supported e-reading devices.</p>

<p><strong>Resources</strong></p>

<ul>
  <li><a href="http://robert.penz.name/440/howto-install-adobe-digital-editions-on-ubuntu-12-04-and-use-it-with-an-e-book-reader/">Howto install Adobe Digital Editions on Ubuntu 12.04 and use it with an e-book reader</a></li>
  <li><a href="http://askubuntu.com/questions/32549/using-adobe-digital-editions-to-transfer-books-to-the-nook-or-a-workaround/308569#308569">Using Adobe Digital Editions to transfer books to the Nook, or a workaround</a></li>
</ul>]]></content><author><name>Alevtina Verbovetskaya</name></author><category term="general" /><category term="technology" /><summary type="html"><![CDATA[I installed Ubuntu but panicked when I couldn't install Adobe Digital Editions for my e-reader—until I discovered how to use Wine and Winetricks to get ADE working perfectly.]]></summary></entry><entry><title type="html">Linking to Aleph OPAC and search results</title><link href="https://verbovetskaya.com/blog/linking-to-aleph-opac-and-search-results/" rel="alternate" type="text/html" title="Linking to Aleph OPAC and search results" /><published>2013-10-28T00:00:00+00:00</published><updated>2014-08-01T00:00:00+00:00</updated><id>https://verbovetskaya.com/blog/linking-to-aleph-opac-and-search-results</id><content type="html" xml:base="https://verbovetskaya.com/blog/linking-to-aleph-opac-and-search-results/"><![CDATA[<blockquote>
  <p><strong>Note</strong></p>

  <p>This post was updated in August 2014 to reflect the new URL for the CUNY Catalog.</p>
</blockquote>

<p><a href="#linking-to-the-aleph-opac">Linking to the Aleph OPAC</a> is easy. <a href="#linking-to-a-specific-search">Linking to a specific search</a> is… well, it’s not as easy and it requires some practice. I’ll explain how to do them both.</p>

<h3 id="linking-to-the-aleph-opac">Linking to the Aleph OPAC</h3>

<p>I don’t know how other institutions do it but, at CUNY, we encourage folks to <a href="http://www.oclc.org/support/services/ezproxy/documentation/example/opac.en.html">proxy their OPAC links</a>. This ensures that when a user attempts to view an e-resource, he/she will be able to authenticate himself/herself and gain access to that resource. Otherwise, the user will be stuck behind a paywall.</p>

<p>So what does the URL look like? In its simplest form, it’s just the URL to the OPAC prefixed by the proxy URL:</p>

<p><code class="language-plaintext highlighter-rouge">http://central.ezproxy.cuny.edu:2048/login?url=http://libsearch.cuny.edu/F/</code></p>

<p>Of course, this is going just through the central office proxy server (ensuring access only to CUNY-wide e-resources, not campus-specific ones) and doesn’t specify a “local base,” or a library scope, so it defaults to the union (or all CUNY libraries) view. To tailor this link to your specific library, you will need to know your college’s <a href="http://support.cunylibraries.org/libraries/proxy-servers">proxy server</a> and your <a href="http://support.cunylibraries.org/libraries/local-base-values">Aleph local base</a>. Then you’ll end up with a link that looks like this:</p>

<p><code class="language-plaintext highlighter-rouge">https://login.remote.baruch.cuny.edu/login?qurl=http://libsearch.cuny.edu/F/?func=find-b-0&amp;local_base=BARUCH</code></p>

<p>Using this properly formatted URL, your patrons will be defaulted to their local library search scope and they will be pinged for authentication when they reach a licensed e-resource.</p>

<h3 id="linking-to-a-specific-search">Linking to a specific search</h3>

<p>But what about when you want to link to a specific search? For example, a faculty member would like to link to all the library’s holdings of Junot Diaz’s work from her Blackboard course site. How can we help her with this?</p>

<p>It’s not enough to just do a search and then copy &amp; paste the resulting URL. You will be stuck with a unique session ID in that URL that will expire and cause the link to default to the basic search screen. This then leads to confusion and frantic emails. The simplest solution, then, is to take that search result URL…</p>

<p><code class="language-plaintext highlighter-rouge">http://libsearch.cuny.edu/F/7C3C7V4U65QEI7DY79FFUP7LIKY3K1289DEAALI48L6LJF4D34-13445?func=find-e&amp;find_scan_code=FIND_WAU&amp;request=junot+diaz&amp;local_base=LEHMAN</code></p>

<p>…and remove the session ID. In the URL above, it’s the gobbledygook (yes, that’s the technical term for it) after the <code class="language-plaintext highlighter-rouge">F/</code> and before the <code class="language-plaintext highlighter-rouge">?func</code>. So the new, persistent (and proxied!) URL will be:</p>

<p><code class="language-plaintext highlighter-rouge">http://memex.lehman.cuny.edu:2048/login?url=http://libsearch.cuny.edu/F/?func=find-e&amp;find_scan_code=FIND_WAU&amp;request=junot+diaz&amp;local_base=LEHMAN</code></p>

<p>There are several things to note here:</p>

<ul>
  <li>This is scoped to Lehman College and goes through their proxy server. If you want to narrow it to your own library (or broaden it to all the CUNY libraries), choose the appropriate <a href="http://support.cunylibraries.org/libraries/local-base-values">Aleph local base</a> and <a href="http://support.cunylibraries.org/libraries/proxy-servers">proxy server</a>.</li>
  <li>The <code class="language-plaintext highlighter-rouge">find_scan_code</code> parameter has the value <code class="language-plaintext highlighter-rouge">FIND_WAU</code>, which means we’re searching for a keyword (that’s the <code class="language-plaintext highlighter-rouge">find</code> part) in the author field (that’s the <code class="language-plaintext highlighter-rouge">wau</code> part). If you need to perform a different search, you will need to select a different search type (or value for the <code class="language-plaintext highlighter-rouge">find_scan_code</code> parameter):
    <ul>
      <li><code class="language-plaintext highlighter-rouge">FIND_WRD</code>: All Fields</li>
      <li><code class="language-plaintext highlighter-rouge">SCAN_TTL</code>: Title begins with</li>
      <li><code class="language-plaintext highlighter-rouge">SCAN_AUT</code>: Author, last name first</li>
      <li><code class="language-plaintext highlighter-rouge">SCAN_SUL</code>: Subject begins with</li>
      <li><code class="language-plaintext highlighter-rouge">FIND_WTI</code>: Keyword in title</li>
      <li><code class="language-plaintext highlighter-rouge">FIND_WAU</code>: Keyword in author</li>
      <li><code class="language-plaintext highlighter-rouge">FIND_WSU</code>: Keyword in subject</li>
      <li><code class="language-plaintext highlighter-rouge">SCAN_SUC</code>: Children’s subject begins with</li>
      <li><code class="language-plaintext highlighter-rouge">SCAN_SUM</code>: MeSH subject begins with</li>
      <li><code class="language-plaintext highlighter-rouge">SCAN_SHL</code>: Call number</li>
      <li><code class="language-plaintext highlighter-rouge">SCAN_ISBN</code>: Browse ISBN</li>
      <li><code class="language-plaintext highlighter-rouge">SCAN_ISSN</code>: Browse ISSN</li>
      <li><code class="language-plaintext highlighter-rouge">SCAN_SYS</code>: Browse Aleph system number</li>
    </ul>
  </li>
  <li>The <code class="language-plaintext highlighter-rouge">request</code> parameter is where you enter your query. Spaces need to be replaced with a plus sign (+). In our example above, notice how the query reads <code class="language-plaintext highlighter-rouge">junot+diaz</code>.</li>
</ul>

<p>It is also possible to construct a much more complicated URL: <code class="language-plaintext highlighter-rouge">https://login.remote.baruch.cuny.edu/login?qurl=http://libsearch.cuny.edu/F/?func=find-c&amp;ccl_term=wow%3Dbb%20and%20wti%3DAmerican+directories&amp;local_base=U-JOURNAL</code></p>

<p>Here, instead of a <code class="language-plaintext highlighter-rouge">find_scan_code</code>, we’re using a <code class="language-plaintext highlighter-rouge">ccl_term</code> (Common Command Language), which is a way to construct a more complex search in the URL. Furthermore, the query for the <a href="http://support.cunylibraries.org/libraries/own-codes">2-letter OWN code</a> (<code class="language-plaintext highlighter-rouge">wow=bb</code>) and keyword in title (<code class="language-plaintext highlighter-rouge">wti=American+directories</code>) used in the <code class="language-plaintext highlighter-rouge">ccl_term</code> parameter in this example includes escape sequences for some of the following characters:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">=</code> represented as <code class="language-plaintext highlighter-rouge">%3D</code></li>
  <li><code class="language-plaintext highlighter-rouge">"</code> represented as <code class="language-plaintext highlighter-rouge">%22</code></li>
  <li><code class="language-plaintext highlighter-rouge">(</code> represented as <code class="language-plaintext highlighter-rouge">%28</code></li>
  <li><code class="language-plaintext highlighter-rouge">)</code> represented as <code class="language-plaintext highlighter-rouge">%29</code></li>
  <li>(space) represented as <code class="language-plaintext highlighter-rouge">%20</code></li>
</ul>

<p>These characters have to be escaped in the <code class="language-plaintext highlighter-rouge">ccl_term</code> parameter. For a list of the CCL terms, see the <a href="http://libsearch.cuny.edu/F/?func=file&amp;file_name=help-1#ccl">CUNY Catalog help files</a>.</p>

<h3 id="embedding-a-search-box">Embedding a search box</h3>

<p>Instructions for embedding a search box to the CUNY Catalog from anywhere (e.g., LibGuides, SerialsSolutons, etc.) are too long to include in this post. However, they are available on the <a href="http://support.cunylibraries.org/systems/aleph/web-opac/search-box">Support @ OLS</a> website.</p>]]></content><author><name>Alevtina Verbovetskaya</name></author><category term="ils" /><category term="aleph" /><category term="technology" /><summary type="html"><![CDATA[Linking to Aleph OPAC searches requires removing session IDs from URLs and using specific parameters like find_scan_code—here's how to create persistent, proxied links.]]></summary></entry><entry><title type="html">User-triggered error reporting in EZproxy</title><link href="https://verbovetskaya.com/blog/user-triggered-error-reporting-in-ezproxy/" rel="alternate" type="text/html" title="User-triggered error reporting in EZproxy" /><published>2013-10-18T00:00:00+00:00</published><updated>2013-10-18T00:00:00+00:00</updated><id>https://verbovetskaya.com/blog/user-triggered-error-reporting-in-ezproxy</id><content type="html" xml:base="https://verbovetskaya.com/blog/user-triggered-error-reporting-in-ezproxy/"><![CDATA[<p>Back in March, my colleague enlisted me to help him roll out mobile-friendly interfaces for all centrally-hosted EZproxy instances. (My office provides support for all 21 libraries in CUNY. Half of the libraries host their own proxy servers while the others rely on us to host and maintain their instances.) While I was at it, I decided to spruce it up a little bit and make it so that users can send error reports if they reach <a href="http://www.oclc.org/support/services/ezproxy/documentation/errorpages.en.html">needhost.htm</a>:</p>

<p><img src="/assets/img/cuny_ezproxy_-_needhost.png" alt="Screenshot" /></p>

<p>It collects information in hidden input fields so all the user sees is a “Submit” button. This is done with a Google Form and some JavaScript. To implement similar functionality for your EZproxy server:</p>

<ol>
  <li>Create a <a href="https://docs.google.com/forms/">Google Form</a> with 4 fields: referring URL, user agent, requested URL, and requested host. (Don’t spend too much time picking a template: no one will see this form since we’ll be embedding it into EZproxy.)</li>
  <li>Create a new spreadsheet that will save the responses (by clicking on the “Choose response destination” button in the toolbar) and click on the “View live form” button.</li>
  <li>Right-click and view the source code of the form. Find the following items:
    <ul>
      <li><code class="language-plaintext highlighter-rouge">&lt;form&gt;</code> tag<br />
  note the URL that is its “action” parameter (in the form of <code class="language-plaintext highlighter-rouge">https://docs.google.com/forms/d/[FORM_ID]/formResponse</code>, where <code class="language-plaintext highlighter-rouge">[FORM_ID]</code> is a long string of characters)</li>
      <li><code class="language-plaintext highlighter-rouge">&lt;input&gt;</code> elements<br />
  note the name of each (in the form of <code class="language-plaintext highlighter-rouge">entry.[xxxxxx]</code>, where <code class="language-plaintext highlighter-rouge">[xxxxxx]</code> is a string of numeric characters)</li>
    </ul>
  </li>
  <li>In your EZproxy <code class="language-plaintext highlighter-rouge">docs</code> directory, edit <code class="language-plaintext highlighter-rouge">needhost.htm</code> and insert the following into the body of the page (replacing <code class="language-plaintext highlighter-rouge">[FORM_ID]</code> and <code class="language-plaintext highlighter-rouge">entry.[xxxxxx]</code> with the names from your form):</li>
</ol>

<figure class="highlight"><pre><code class="language-html" data-lang="html"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code"><pre><span class="nt">&lt;h3&gt;</span>Oops!<span class="nt">&lt;/h3&gt;</span>
<span class="nt">&lt;p&gt;</span>There appears to be a problem with the library's setup of the material you are trying to access. The host <span class="nt">&lt;em&gt;</span>^H<span class="nt">&lt;/em&gt;</span> is not recognized by the proxy server.<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;p&gt;</span>If you arrived here by following a link and believe this resource should be accessible, let us know of this error by hitting the "Submit" button below:<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;script </span><span class="na">type=</span><span class="s">"text/javascript"</span><span class="nt">&gt;</span><span class="kd">var</span> <span class="nx">submitted</span><span class="o">=</span><span class="kc">false</span><span class="p">;</span><span class="nt">&lt;/script&gt;</span>
<span class="nt">&lt;iframe</span> <span class="na">id=</span><span class="s">"hidden_iframe"</span> <span class="na">style=</span><span class="s">"display: none;"</span> <span class="na">name=</span><span class="s">"hidden_iframe"</span><span class="nt">&gt;&lt;/iframe&gt;&lt;/pre&gt;</span>
<span class="nt">&lt;form</span> <span class="na">id=</span><span class="s">"needhost_form"</span> <span class="na">action=</span><span class="s">"https://docs.google.com/forms/d/[FORM_ID]/formResponse"</span> <span class="na">method=</span><span class="s">"POST"</span> <span class="na">target=</span><span class="s">"hidden_iframe"</span><span class="nt">&gt;</span>
	<span class="c">&lt;!-- Below: Referring URL --&gt;</span>
	<span class="nt">&lt;input</span> <span class="na">dir=</span><span class="s">"auto"</span> <span class="na">name=</span><span class="s">"entry.[refurl]"</span> <span class="na">type=</span><span class="s">"hidden"</span> <span class="na">value=</span><span class="s">""</span> <span class="nt">/&gt;</span>
	<span class="c">&lt;!-- Below: User Agent --&gt;</span>
	<span class="nt">&lt;input</span> <span class="na">dir=</span><span class="s">"auto"</span> <span class="na">name=</span><span class="s">"entry.[usragt]"</span> <span class="na">type=</span><span class="s">"hidden"</span> <span class="na">value=</span><span class="s">""</span> <span class="nt">/&gt;</span>
	<span class="c">&lt;!-- Below: Requested URL --&gt;</span>
	<span class="nt">&lt;input</span> <span class="na">dir=</span><span class="s">"auto"</span> <span class="na">name=</span><span class="s">"entry.[requrl]"</span> <span class="na">type=</span><span class="s">"hidden"</span> <span class="na">value=</span><span class="s">"^V"</span> <span class="nt">/&gt;</span>
	<span class="c">&lt;!-- Below: Requested Host --&gt;</span>
	<span class="nt">&lt;input</span> <span class="na">dir=</span><span class="s">"auto"</span> <span class="na">name=</span><span class="s">"entry.[reqhst]"</span> <span class="na">type=</span><span class="s">"hidden"</span> <span class="na">value=</span><span class="s">"^H"</span> <span class="nt">/&gt;</span>
	<span class="nt">&lt;script&gt;</span>
		<span class="nb">document</span><span class="p">.</span><span class="nx">forms</span><span class="p">[</span><span class="dl">"</span><span class="s2">needhost_form</span><span class="dl">"</span><span class="p">][</span><span class="dl">"</span><span class="s2">entry.[refurl]</span><span class="dl">"</span><span class="p">].</span><span class="nx">value</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">referrer</span><span class="p">;</span>	<span class="c1">// referring URL</span>
		<span class="nb">document</span><span class="p">.</span><span class="nx">forms</span><span class="p">[</span><span class="dl">"</span><span class="s2">needhost_form</span><span class="dl">"</span><span class="p">][</span><span class="dl">"</span><span class="s2">entry.[usragt]</span><span class="dl">"</span><span class="p">].</span><span class="nx">value</span> <span class="o">=</span> <span class="nb">navigator</span><span class="p">.</span><span class="nx">userAgent</span><span class="p">;</span>	<span class="c1">// user agent</span>
	<span class="nt">&lt;/script&gt;</span>
	<span class="nt">&lt;input</span> <span class="na">name=</span><span class="s">"draftResponse"</span> <span class="na">type=</span><span class="s">"hidden"</span> <span class="na">value=</span><span class="s">"[]"</span> <span class="nt">/&gt;</span>
	<span class="nt">&lt;input</span> <span class="na">name=</span><span class="s">"pageHistory"</span> <span class="na">type=</span><span class="s">"hidden"</span> <span class="na">value=</span><span class="s">"0"</span> <span class="nt">/&gt;</span>
	<span class="nt">&lt;input</span> <span class="na">id=</span><span class="s">"submit_btn"</span> <span class="na">name=</span><span class="s">"submit"</span> <span class="na">type=</span><span class="s">"submit"</span> <span class="na">value=</span><span class="s">"Submit"</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/form&gt;</span>	
</pre></td></tr></tbody></table></code></pre></figure>

<p>Note the <code class="language-plaintext highlighter-rouge">&lt;script&gt;</code> and <code class="language-plaintext highlighter-rouge">&lt;iframe&gt;</code> tags in the code. What are they?</p>

<ul>
  <li>Lines 4-6
    <ul>
      <li>Upon hitting the “Submit” button in a Google Form, users are taken to a Google confirmation page. We want the user to stay on our site so we have to force this behavior on the EZproxy server.</li>
      <li>By creating a Boolean variable (<code class="language-plaintext highlighter-rouge">var submitted=false;</code>, line 4) whose value will change upon the form submit (<code class="language-plaintext highlighter-rouge">&lt;form [...] onsubmit="submitted=true;"&gt;</code>, line 6) and trigger a script that will change the window’s location (<code class="language-plaintext highlighter-rouge">&lt;iframe [...] onload="if(submitted) {window.location='public/needhost_submit.html';_"&gt;</code>, line 5) to a page that you will have created and populated with a nice message, assuring the user the issue will be addressed posthaste.</li>
    </ul>
  </li>
  <li>Lines 15-18
    <ul>
      <li>We fill two of the <code class="language-plaintext highlighter-rouge">&lt;input&gt;</code> elements with data we grab from the browser: referring URL (line 16) and user agent (line 17).</li>
    </ul>
  </li>
</ul>

<p><em>Et voilà!</em> You now have EZproxy error reports, submitted by users trying to access actual resources, in a spreadsheet in your Google Drive account:</p>

<p><img src="/assets/img/cuny_ezproxy_-_needhost_form_submissions.png" alt="Screenshot" /></p>

<p>By default, you do not get email notifications when a form is submitted. You can turn on this functionality in the Google Spreadsheet but all it will do is inform you when a user has submitted the form, without actually providing you with the form data in the email.</p>

<p>To overcome this, we’ll create a script that will send the results to you by email as soon as a user submits the form. In the response spreadsheet, go to <code class="language-plaintext highlighter-rouge">Tools &gt; Script editor &gt; Blank Project</code> and paste the following code into the editor (replacing placeholder variable values with your own):</p>

<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
</pre></td><td class="code"><pre><span class="kd">function</span> <span class="nf">sendFormByEmail</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
	<span class="kd">var</span> <span class="nx">emailSubject</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">Request to add host to EZproxy config.txt</span><span class="dl">"</span><span class="p">;</span>  
	<span class="c1">// Set with your email address or a comma-separated list of email addresses.</span>
	<span class="kd">var</span> <span class="nx">yourEmail</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">[EMAIL_ADDRESS]</span><span class="dl">"</span><span class="p">;</span>
	<span class="c1">// Set with your spreadsheet's key, found in the URL when viewing your spreadsheet.</span>
	<span class="kd">var</span> <span class="nx">docKey</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">[FORM_ID]</span><span class="dl">"</span><span class="p">;</span>
	<span class="c1">// If you want the script to auto send to all of the spreadsheet's editors, set this value as 1.</span>
	<span class="c1">// Otherwise set to 0 and it will send to the yourEmail values.</span>
	<span class="kd">var</span> <span class="nx">useEditors</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
	<span class="k">if </span><span class="p">(</span><span class="nx">useEditors</span><span class="p">)</span> <span class="p">{</span>
		<span class="kd">var</span> <span class="nx">editors</span> <span class="o">=</span> <span class="nx">DriveApp</span><span class="p">.</span><span class="nf">getFileById</span><span class="p">(</span><span class="nx">docKey</span><span class="p">).</span><span class="nf">getEditors</span><span class="p">();</span>
		<span class="k">if </span><span class="p">(</span><span class="nx">editors</span><span class="p">)</span> <span class="p">{</span> 
			<span class="kd">var</span> <span class="nx">notify</span> <span class="o">=</span> <span class="nx">editors</span><span class="p">.</span><span class="nf">join</span><span class="p">(</span><span class="dl">'</span><span class="s1">,</span><span class="dl">'</span><span class="p">);</span>
		<span class="p">}</span> <span class="k">else</span> <span class="kd">var</span> <span class="nx">notify</span> <span class="o">=</span> <span class="nx">yourEmail</span><span class="p">;</span>
	<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
		<span class="kd">var</span> <span class="nx">notify</span> <span class="o">=</span> <span class="nx">yourEmail</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="c1">// The variable e holds all the submission values in an array.</span>
	<span class="c1">// Loop through the array and append values to the body.</span>
	<span class="kd">var</span> <span class="nx">s</span> <span class="o">=</span> <span class="nx">SpreadsheetApp</span><span class="p">.</span><span class="nf">getActive</span><span class="p">().</span><span class="nf">getSheetByName</span><span class="p">(</span><span class="dl">"</span><span class="s2">Form Responses</span><span class="dl">"</span><span class="p">);</span>
	<span class="kd">var</span> <span class="nx">headers</span> <span class="o">=</span> <span class="nx">s</span><span class="p">.</span><span class="nf">getRange</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="nx">s</span><span class="p">.</span><span class="nf">getLastColumn</span><span class="p">()).</span><span class="nf">getValues</span><span class="p">()[</span><span class="mi">0</span><span class="p">];</span>
	<span class="kd">var</span> <span class="nx">message</span> <span class="o">=</span> <span class="dl">""</span><span class="p">;</span>
	<span class="k">for</span><span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">headers</span><span class="p">)</span> <span class="p">{</span>
		<span class="nx">message</span> <span class="o">+=</span> <span class="nx">headers</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">+</span> <span class="dl">'</span><span class="s1"> = </span><span class="dl">'</span><span class="o">+</span> <span class="nx">e</span><span class="p">.</span><span class="nx">namedValues</span><span class="p">[</span><span class="nx">headers</span><span class="p">[</span><span class="nx">i</span><span class="p">]].</span><span class="nf">toString</span><span class="p">()</span> <span class="o">+</span> <span class="dl">'</span><span class="se">\n\n</span><span class="dl">'</span><span class="p">;</span> 
	<span class="p">}</span>
	<span class="nx">MailApp</span><span class="p">.</span><span class="nf">sendEmail</span><span class="p">(</span><span class="nx">notify</span><span class="p">,</span> <span class="nx">emailSubject</span><span class="p">,</span> <span class="nx">message</span><span class="p">);</span> 
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></figure>

<p>Click <code class="language-plaintext highlighter-rouge">File &gt; Save</code> and give the project a name (such as <code class="language-plaintext highlighter-rouge">needhost_notify</code>). Go to <code class="language-plaintext highlighter-rouge">Resources &gt; Current project's triggers</code>. Click “No triggers set up. Click here to add one now.” to add a trigger. Ensure the following values are selected in the drop-down menus: <code class="language-plaintext highlighter-rouge">sendFormByEmail</code>, <code class="language-plaintext highlighter-rouge">From spreadsheet</code>, <code class="language-plaintext highlighter-rouge">On form submit</code>. Click “Save.”</p>

<p>A message will be shown to authorize the script; click “Continue.” Read the terms and click “Accept.” It will approve the authorization for the trigger and bring you back to the code editor. You can now close the editor and go back to your spreadsheet because you’re all set!</p>

<p><img src="/assets/img/cuny_ezproxy_-_needhost_email.png" alt="Screenshot" /></p>

<p>You should now have a form, embedded in your EZproxy’s needhost.htm file, that users can submit to self-report problems accessing resources. Their responses will be logged in a spreadsheet in your Google Drive account and emailed to you upon submission. Go forth and troubleshoot!</p>

<p><strong>Resources</strong></p>

<ul>
  <li><a href="http://pluto.potsdam.edu/ezproxywiki/index.php/NeedHost_alerts_via_Google_Form">NeedHost alerts via Google Form</a></li>
  <li><a href="http://www.blogxpertise.com/2012/04/tip-making-google-doc-submission-form.html">Tip: Making a Google Doc submission form email you the results</a></li>
</ul>]]></content><author><name>Alevtina Verbovetskaya</name></author><category term="proxy" /><category term="ezproxy" /><category term="technology" /><summary type="html"><![CDATA[I enhanced EZproxy's needhost.htm with a Google Form that lets users report access errors—collecting browser data automatically and emailing me the results for quick troubleshooting.]]></summary></entry><entry><title type="html">Drupal 7: Friendly URLs for personal user contact forms</title><link href="https://verbovetskaya.com/blog/drupal-7-friendly-urls-for-personal-user-contact-forms/" rel="alternate" type="text/html" title="Drupal 7: Friendly URLs for personal user contact forms" /><published>2013-09-17T00:00:00+00:00</published><updated>2013-09-17T00:00:00+00:00</updated><id>https://verbovetskaya.com/blog/drupal-7-friendly-urls-for-personal-user-contact-forms</id><content type="html" xml:base="https://verbovetskaya.com/blog/drupal-7-friendly-urls-for-personal-user-contact-forms/"><![CDATA[<p>I’ve been working with <a href="http://www.drupal.org/">Drupal</a> for the last year in my current position (as University Web &amp; Mobile Systems Librarian at the <a href="http://www.cuny.edu/">City University of New York</a>) and I have a love-hate relationship with it. I appreciate its power and agility but curse its complexity, especially for the lay end-user. The biggest project thus far has been moving the department’s support site from Drupal 6 to the newest version of Drupal 7. There’s no easy way to accomplish this so I’ve been doing it manually, using <a href="https://drupal.org/project/node_export">Node Export</a> and <a href="https://drupal.org/project/feeds">Feeds</a> to move data from one instance to the other. It’s been tedious work but manageable since it’s a small site.</p>

<p>One of the biggest <a href="http://knowyourmeme.com/memes/y-u-no-guy">Y U NO WORK!?</a> moments was trying to figure out why users’ personal contact forms were not conforming to the friendly URL pattern I’d set up with <a href="https://drupal.org/project/pathauto/">Pathauto</a>:</p>

<p><img src="/assets/img/d7_-_pathauto_-_user_paths.png" alt="Drupal 7 Pathauto User Paths" /></p>

<p>No matter what I did, the users’ contact forms were always located at <code class="language-plaintext highlighter-rouge">user/[uid]/contact</code> (and not at the desired <code class="language-plaintext highlighter-rouge">users/[user:name]/contact</code>). The thing that confused me the most, though, was that this wasn’t a problem in our current D6 instance and that’s because Pathauto 6.x-1.6 contains a separate field for user contact forms paths:</p>

<p><img src="/assets/img/d6_-_pathauto_-_user_paths.png" alt="Drupal 6 Pathauto User Paths" /></p>

<p>Frustratingly, there’s no such field in Pathauto 7.x-1.2.</p>

<p>…There is, however, <a href="https://drupal.org/project/subpathauto">Sub-pathauto</a>— a totally separate module that does exactly what it sounds like. It creates sub-path URL aliases for patterns created with Pathauto. I installed it<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup>] as soon as I learned about its existence:</p>

<figure class="highlight"><pre><code class="language-terminal" data-lang="terminal"><span class="gp">$</span><span class="w"> </span>drush dl subpathauto
<span class="gp">$</span><span class="w"> </span>drush en <span class="nt">-y</span> subpathauto
<span class="gp">$</span><span class="w"> </span>drush cc all</code></pre></figure>

<p>And, <em>presto</em>! Users’ personal contact forms are now at the desired <code class="language-plaintext highlighter-rouge">users/[user:name]/contact</code> location. (However, they are also at the previous—and undesired—<code class="language-plaintext highlighter-rouge">user/[uid]/contact</code> location so be sure to install <a href="https://drupal.org/project/redirect">Redirect</a> to remove the duplicated URLs.)</p>

<p>Now why didn’t Pathauto for D7 come standard with this functionality?</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p><a href="https://github.com/drush-ops/drush">Drush</a> is seriously awesome. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Alevtina Verbovetskaya</name></author><category term="cms" /><category term="drupal" /><category term="technology" /><summary type="html"><![CDATA[Migrating from Drupal 6 to 7, I hit a wall when user contact forms wouldn't follow my Pathauto URL patterns—until I discovered the Sub-pathauto module fixed it perfectly.]]></summary></entry><entry><title type="html">Video tutorials a la carte</title><link href="https://verbovetskaya.com/blog/video-tutorials-a-la-carte/" rel="alternate" type="text/html" title="Video tutorials a la carte" /><published>2011-09-27T00:00:00+00:00</published><updated>2011-09-27T00:00:00+00:00</updated><id>https://verbovetskaya.com/blog/video-tutorials-a-la-carte</id><content type="html" xml:base="https://verbovetskaya.com/blog/video-tutorials-a-la-carte/"><![CDATA[<p>When we last met, I gave you a behind-the-scenes look at how <a href="https://alevtina.commons.gc.cuny.edu/2011/06/30/the-one-where-four-librarians-become-superstars/">four librarians became superstars</a>. In this installment, I show you what the finished product looks like…</p>

<p><img src="/assets/img/lc_video_tutorials.png" alt="Screenshot of the Lehman College Library's video tutorials page" /></p>

<p>The <a href="https://www.lehman.edu/library/video-tutorials.php">videos</a> turned out exactly as I had envisioned them and I am incredibly proud of all the work my colleagues and I put into them. The website on which these videos are displayed also allows students to email the videos to themselves for later viewing, which will be crucial at the conclusions of the library’s information literacy workshops.</p>

<p>This project was truly a joint effort. In addition to the staff in the library, I collaborated with the campus <a href="https://www.lehman.edu/multimedia-center/">Multimedia Center</a> to record the videos and with the college <a href="https://www.lehman.edu/itr/">IT Division</a> to create the website and mail form. I feel extremely grateful to have gotten the opportunity to work cooperatively with these talented folks across the Lehman College campus.</p>

<p>I am no longer the Instructional Technologies Librarian at Lehman College but I am still on board as an adjunct. (I am also an adjunct in the library at <a href="https://www.citytech.cuny.edu/">City Tech</a>.) I will no longer be contributing to this or the <a href="https://wp.lehman.edu/library/comics/">webcomic project</a> but I am excited to see these tutorials grow and evolve. They’re like my children and this is akin to watching them grow up. It’s bittersweet.</p>]]></content><author><name>Alevtina Verbovetskaya</name></author><category term="instruction" /><category term="teaching" /><category term="tutorials" /><category term="videos" /><summary type="html"><![CDATA[Our library instructional videos turned out exactly as envisioned—short tutorials students can email to themselves, created through collaboration across campus departments.]]></summary></entry></feed>