Category: code

Convert a PHP/MySQL site to Jamstack and host on Github Pages

One of the first items on my sabbatical to do list last year was to convert the Camp La Jolla Military Park website to a static Jamstack site hosted at Github Pages. This post documents that process.

I originally created the site as a research tool using PHP and a MySQL database for data entry, to record, organize, and ultimately publish research about the military history of UCSD. Moving the project to Github Pages would simplify maintenance and hosting costs, but was no small task. Technically it didn’t cost me extra to host, but the domain was $20/year, which adds up. Further, maintaining a PHP/MySQL website with a custom admin tool requires a bit of overhead for security and updates. Additionally, I wanted to continue having the benefit of using template engines or some way to include files (like PHP’s require()) to save time coding the site.

There are a plethora of tools available to publish a database-driven site on a static host. They mostly can be categorized as follows (ordered by most to least dynamic data sources):

  • Move the database to a remote service like Firebase, Atlas, et al. — ⚠️ Ultimately creates vendor lock-in, potential hidden costs, and probably more maintenance issues in the future.
  • Create a static version of the database by converting MySQL to flat files (JSON, CSV, etc.), which still allows for querying using one of various tools — 🤔 This method is interesting, because it still decouples the data from the presentation and allows for potentially more options later, including a remote database. I am already using this in various forms but worry again about maintenance, or issues with the client’s ability to manipulate the data as needed.
  • Generate a static version of the site, including all its pages which contain the data formerly dynamically inserted from MySQL. — 🤔 I like this concept, and have been using it to auto-publish my class lectures and tutorials using Markdown and Grunt with Marp. Plus, there are many site generators to choose from, which I explore below.
  • Scrape the site and save pages as static files. After all, everything is static once the HTML is rendered on the frontend. — ⚠️ While fast, this requires the site be built first and would make updates difficult.

Essential Concepts

Here I outline some concepts on rendering. See SSR vs CSR vs ISR vs SSG for a more in-depth look:

  • Client-Side Rendering (CSR) (e.g. Single-Page Application (SPA)) – JS renders pages in client’s browser with empty HTML files + raw data from the server. (e.g. React, Vue, Angular)
  • Server-Side Rendering (SSR) (e.g. Fullstack) – Generates pages on server with dynamic data before delivering to client. Improves SEO and loading, decreases server performance. (e.g. EJS, PHP, or Next.js)
  • Static Site Generation (SSG) (e.g. JAMStack) – Pre-renders all pages as static HTML during build process. Fast loading times, enhanced security, and dynamic content can still be achieved via “islands”.
  • Incremental Static Regeneration (ISR) – Combines SSR and SSG to pre-render static pages during build time while periodically regenerating specific pages with updated data.
  • Edge-Side Rendering (ESR) – Rendering process is pushed to the CDN’s edge servers which handles requests and generates HTML. Requires Nitro engine.

Requirements

Requirements for most of the projects I mention above.

  1. Javascript-based
  2. The data will be static, but editable using Git
  3. The data should be searchable using a tool like chosen
  4. The site design will be simple, but I should have creative control
  5. The site will be public, and be presented mostly using the same design as the original site
  6. HTML/CSS validation + Accessibility checks
  7. Convert from Google Maps to Leaflet
  8. Host the site on Github Pages

While planning the project I also wanted to select a method I could use for other potential static (or nearly static) sites like:

  1. A new site documenting the hundreds of examples and overlapping categories of Critical Web Design and internet art I’ve been collecting for an upcoming book. Update: I built it with SvelteKit
  2. Converting tallysavestheinternet.com to a static site (currently SSR) and unlinking the extension from the server to use local data only
  3. Moving away from WordPress more generally (and its security problems) and blogging with Markdown instead, starting with this blog (NO MORE TYPING IN A WEB FORM!!)

It’s nice to learn new tools. I already have some experiences with React, Next.js, and Vue.js, but wouldn’t say I’m confident in any. I found that publishing apps using React Native is very frustrating and unreliable, and my general distrust of Facebook makes me lean towards Vue. Still, I went in with an open attitude.

Tool Comparison

A breakdown of some tools I considered. Some of the icons are clickable…

FrameworkSPASSRSSGMDThemesSearchCons
Jekyll❌❌✅✅✅?❌ Ruby
Hugo❌❌✅✅✅?❌ Go
Astro✅✅✅✅✅✅React, Vue, Svelte in dynamic islands, simple routing
Vue.js✅✅✅✅✅?✅ vuepress
Nuxt.js✅✅✅✅✅?Built on Vue
SvelteKit✅✅✅✅✅✅MD rendering not native but supported via MDX
Next.js✅✅✅✅✅✅MD rendering not native but supported via MDX

Next

My experience with Next.js SSG was painful.

  • Constantly running into subtle changes in syntax across versions
  • Adding an image is ridiculously difficult.
  • Exporting the SSG ultimately created dead links, packaged up in Next code that was hard to understand.
  • So much automation to make a static site in the end you can’t do anything unless you have the exact right code, in the right version, in the right paths.
  • Error messages are rarely helpful or pinpoint the line number causing the issue in the stack.
  • I followed so many tutorials that ultimately ended in dead-ends, incorrect versions, or that completely didn’t work.

Astro

I ended up choosing Astro for the final project, which can be seen here https://omundy.github.io/camplajolla/. While they appear to have many similarities, I found Astro soooooo much easier than Next.js. It’s fairly simple to install, even using a starter theme, and it didn’t take long torip out tailwind to add bootstrap.

Escape from music subscription services

Like the rest of the world, I’ve moved on from CDs for music. However, since I’ve converted all my discs to digital format, and I’m not likely to pay for a smartphone that can hold 140 GB of audio, my music collection has only received attention while I’m bleeding MTB brakes in my garage. Since I recently upgraded my radio in my car to a Boss Carplay radio, which supports loading media from a thumb drive, I decided to try to revive my old tunes.

The first issue is that while the Boss Radio BE7ACP.WX (an upgrade from the original BE920WCPA I purchased, and had to warranty once for the screen flashing on and off repeatedly, and another time for the screen information appearing completely upside down!) only supports MP3 files (and a thumb drive formatted with FAT32 with a max size of 32 GB!~). No problem, this can be done with FFMPEG…

However, what if you have 140 GB of music, with a folder for each artist, and inside that, a folder for each album?

Thus I share this project github.com/omundy/convert-music-library, which will convert an entire iTunes (or other) music library from .m4a to .mp3 (or .wav), maintaining the original directory structure (Artist/Album/Song). It still requires FFMPEG, and Node, but it may help someone else out there avoid locking themselves into a stupid subscription service. Enjoy!

Escape from music subscription services

Upcoming workshop at FSU, “I Know Where Your Cat Lives”: The Process of Mapping Big Data for Inconspicuous Trends

I’m doing a workshop / lecture as part of the ongoing Digital Scholars digital humanities discussion group here at Florida State University. Workshop is free and open to the public.

Wednesday, March 25, 2:00-3:30 pm
Fine Arts Building (FAB) 320A [530 W. Call St. map]

I Know Where Your Cat Lives

“I Know Where Your Cat Lives”: The Process of Mapping Big Data for Inconspicuous Trends

Big Data culture has its supporters and its skeptics, but it can have critical or aesthetic value even for those who are ambivalent. How is it possible, for example, to consider data as more than information — as the performance of particular behaviors, the practice of communal ideals, and the ethic motivating new media displays? Professor Owen Mundy from FSU’s College of Fine Arts invites us to take up these questions in a guided exploration of works of art that will highlight what he calls “inconspicuous trends.” Using the “I Know Where Your Cat Lives” project as a starting point, Professor Mundy will introduce us to the technical and design process for mapping big data in projects such as this one, showing us the various APIs (Application Program Interfaces) that are constructed to support them and considering the various ways we might want to visualize their results.

This session offers a hands-on demonstration and is designed with a low barrier of entry in mind. For those completely unfamiliar with APIs, this session will serve as a useful introduction, as Professor Mundy will walk us through the process of connecting to and retrieving live social media data from the Instagram API and rendering it using the Google Maps API. Participants should not worry if they do not have expertise in big data projects or are still learning the associated vocabulary. We come together to learn together, and all levels of skill will be accommodated, as will all attitudes and leanings. Desktop computers are installed in FAB 320A, but participants are welcome to bring their own laptops and wireless devices.

Participants are encouraged to read the following in advance of the meeting:

and to browse the following resources for press on Mundy’s project:

For further (future) reading:

I Know Where Your Cat Lives launched

I just launched a new ongoing project this week. Here’s the text, a video and some screenshots. I’ll post more about how I made it soon.

Welcome to the today’s internet—you can buy anything, every website is tracking your every move, and anywhere you look you find videos and images of cats. Currently, there are 15 million images tagged with the word “cat” on public image hosting sites, and daily thousands more are uploaded from unlimited positions on the globe.

“I Know Where Your Cat Lives” iknowwhereyourcatlives.com is a data experiment that visualizes a sample of 1 million public pics of cats on a world map, locating them by the latitude and longitude coordinates embedded in their metadata. The cats were accessed via publicly available APIs provided by popular photo sharing websites. The photos were then run through various clustering algorithms using a supercomputer at Florida State University in order to represent the enormity of the data source.

This project explores two uses of the internet: the sociable and humorous appreciation of domesticated felines, and the status quo of personal data usage by startups and international megacorps who are riding the wave of decreased privacy for all. This website doesn’t visualize all of the cats on the net, only the ones that allow you to track where their owners have been.

Folks can also contribute to a kickstarter to help with hosting costs.

I Know Where Your Cat Lives

I Know Where Your Cat Lives

I Know Where Your Cat Lives

I Know Where Your Cat Lives

I Know Where Your Cat Lives

I Know Where Your Cat Lives

I Know Where Your Cat Lives

Term vs. Term for Digital Public Library of America hackathon

I made a small app to compare the number of search results for two phrases from the Digital Public Library of America for a hackathon / workshop here at Florida State next week.

https://omundy.github.io/term-vs-term/

dpla term vs term

Digital Humanities Hackathon II – Digital Public Library of America

Monday, April 21, 2:00-3:30 p.m.
Strozier Library, Scholars Commons Instructional Classroom [MAP]

The Digital Scholars Reading and Discussion Group will simulate its second “hackathon” on April 21, allowing participants to learn more about the back-end structure of the Digital Public Library of America. With its April 2013 launch, the DPLA became the first all-digital library that aggregates metadata from collections across the country, making them available from a single point of access. The DPLA describes itself as a freely available, web-based platform for digitized cultural heritage projects as well as a portal that connects students, teachers, scholars, and the public to library resources occurring on other platforms.

From a critical point of view, the DPLA simultaneously relies on and disrupts the principles of location and containment, making its infrastructure somewhat interesting to observe.

In this session, we will visit the DPLA’s Application Programming Interface (API) codex to observe some of the standards that contributed to its construction. We will consider how APIs function, how and why to use them, and who might access their metadata and for what purposes. For those completely unfamiliar with APIs, this session will serve as a useful introduction, as well as a demonstration of why a digital library might also want to serve as an online portal. For those more familiar with APIs, this session will serve as an opportunity to try on different tasks using the metadata that the DPLA aggregates from collections across the country.

At this particular session, we are pleased to be joined by Owen Mundy from FSU Department of Art and Richard Urban from FSU College of Communication and Information, who have considered different aspects of working with APIs for projects such as the DPLA, including visualization and graphics scripting, and developing collections dashboards.

As before, the session is designed with a low barrier of entry in mind, so participants should not worry if they do not have programming expertise or are still learning the vocabulary associated with open-source projects. We come together to learn together, and all levels of skill are accommodated, as are all attitudes and leanings.

Participants are encouraged to explore the Digital Public Library of America site prior to our meeting and to familiarize themselves with the history of the project. Laptops will be available for checkout, but attendees are encouraged to bring their own.

Give Me My Data visualizations / tutorials

I received two separate emails recently sharing images and sample code for visualization projects produced with the help of Give Me My Data. I’m happy to share them both here:

Give Me My Data

Alex Hornbake posted a visualization mapping Facebook friend locations and connections in D3. You can view it here and there’s a Gist with all the code here. His image shows where his connections are located, or have move to or from. As abstract and beautiful as the image is, one can still make out a rough outline of the United States and even guess at specific cities like Atlanta, New York, Miami, and Los Angeles.

Rik Van Bruggen, of Neo Technology, used the “mutual friends graph” to create an interactive neo4j graph database. Following is more information from the tutorial he produced.

Ever since Facebook promoted its “graph search” methodology, lots of people in our industry have been waking up to the fact that graphs are über-cool. Thanks to the powerful query possibilities, people like Facebook, Twitter, LinkedIn, and let us not forget, Google have been providing us with some of the most amazing technologies. Specifically, the power of the “social network” is tempting many people to get their feet wet, and to start using graph technology. And they should: graphs are fantastic at storing, querying and exploiting social structures, stored in a graph database.

The first step to take was to get access to my own facebook data. Obviously there is the facebook graph api, but I hope that by now you would realise that is just not my cup of tea. Sounded to exhausting :) … So: I found myself a little tool that would allow me to download the data from facebook, in a workable format. Give me my data provides a number of different export options, but I chose the “Mutual Friends Network Graph – as it would give me most info with regards to my actual social network.

png;base64ad8e402bc7ee51e

Use Processing and FFmpeg to export HD video

Video frame exported from Processing

I’ve been trying to find a dependable method for exporting HD video from Processing sketches that contain dynamic data and movement as well as complex 3-dimensional shapes rendered using OpenGL. QuickTime’s screen recording option hogs memory and causes frames to skip, as does ScreenFlow, my usual go-to for screen recording. The best way I have found so far is to export actual resolution PNG files using “save()” and create an HD video using FFmpeg.

FFmpeg is a very fast video and audio converter that can also grab from a live audio/video sources or create and compress video from multiple still images. It is used from the command line and gives one control of bitrates, codecs, formats, resolution, quality, metadata, and many more options for working with video.

To install FFmpeg with Macports
sudo port install ffmpeg

# view help
ffmpeg -h

# list encoders
ffmpeg -encoders

# list codecs
ffmpeg -codecs

# use format
ffmpeg [global_options] {[input_options] -i ‘input_file’} ... {[output_options] ‘output_file’} ...

# make a movie from matching .png files, write over original, codec = libx264 (H.264), framerate = 30, 1 pass, resolution = 1920×1080, video bitrate = 6Mbits, format = mp4
ffmpeg -y -pattern_type glob -i 'p_*.png' -vcodec libx264 -r 30 -q 100 -pass 1 -s 1920x1080 -vb 6M -threads 0 -f mp4 file.mp4

# convert the video file to Apple ProRes codec for use in Final Cut
ffmpeg -y -i file.mp4 -vcodec prores -vb 6M -r 30 -s 1920x1080 -f mov file.mov

# here’s another example conversion command. this one has a much higher bitrate
ffmpeg -y -i file_01.mp4 -b:v 40M -vcodec libx264 -pass 1 file_02.mp4

For example, using this Processing sketch, you generate the PNG files, and then run the code above on the command line to make this file:

Also see this video for a more detailed example

References

Grid, Sequence Me @ Flashpoint Gallery, Washington D.C.

Grid, Sequence Me at Flashpoint Gallery

Surrounded by images of cross-sectioned buildings and source code excerpts, gallery visitors encounter fragments of Washington, DC architecture—a vaguely familiar roofline or grid of office windows—remixed with data and source code representing the latest housing sales in the area. Constantly changing, the live data streams into the gallery from both local sources (DC short sale listings) and national (federal policy sites), emphasizing the effects of related micro-macro shifts.

Grid, Sequence Me at Flashpoint Gallery, screen detail

Grid, Sequence Me at Flashpoint Gallery, screen detail

Generated with custom software, these fragments echo financial systems and housing market fluctuations. They mirror mortgages repackaged and sold, titles lost in administrative tape, and dreams confused by legal jargon. Like the complex financial systems of the housing market heyday, the software generates an infinite number of arrangements. The complexity of unique and dynamically-created algorithmic outcomes contrasts with the comforting predictability referenced in the exhibition’s title, “Grid, Sequence Me.”

—Joelle Dietrick and Owen Mundy

Grid, Sequence Me at Flashpoint Gallery

Grid, Sequence Me at Flashpoint Gallery, sea screen detail

Grid, Sequence Me at Flashpoint Gallery, sea screen detail

Grid, Sequence Me at Flashpoint Gallery, sea screen detail

Grid, Sequence Me at Flashpoint Gallery, sea screen detail

Packet Switching, College of Journalism and Communications at the University of Florida

Joelle and I have completed our Packet Switching (Weimer Hall) commission in the College of Journalism and Communications at the University of Florida. Read about the process for this project here.

Packet Switching (Weimer Hall), detail

Packet Switching (Weimer Hall), (detail) College of Journalism and Communications, University of Florida, inkjet on polyester on panel, 177.5 ft. x 20.21 ft., 2012; Photograph by Steve Johnson / UF College of Journalism and Communications

Packet Switching (Weimer Hall), detail

Packet Switching (Weimer Hall), (detail) College of Journalism and Communications, University of Florida, inkjet on polyester on panel, 177.5 ft. x 20.21 ft., 2012; Photograph by Steve Johnson / UF College of Journalism and Communications

Packet Switching (Weimer Hall), detail

Packet Switching (Weimer Hall), (detail) College of Journalism and Communications, University of Florida, inkjet on polyester on panel, 177.5 ft. x 20.21 ft., 2012; Photograph by Steve Johnson / UF College of Journalism and Communications

Packet Switching (Weimer Hall), detail

Packet Switching (Weimer Hall), (detail) College of Journalism and Communications, University of Florida, inkjet on polyester on panel, 177.5 ft. x 20.21 ft., 2012; Photograph by Steve Johnson / UF College of Journalism and Communications

Packet Switching (Weimer Hall), detail

Packet Switching (Weimer Hall), (detail) College of Journalism and Communications, University of Florida, inkjet on polyester on panel, 177.5 ft. x 20.21 ft., 2012; Photograph by Steve Johnson / UF College of Journalism and Communications

Packet Switching (Weimer Hall), detail

Packet Switching (Weimer Hall), (detail) College of Journalism and Communications, University of Florida, inkjet on polyester on panel, 177.5 ft. x 20.21 ft., 2012; Photograph by Steve Johnson / UF College of Journalism and Communications

Packet Switching (Weimer Hall), detail

Packet Switching (Weimer Hall), (detail) College of Journalism and Communications, University of Florida, inkjet on polyester on panel, 177.5 ft. x 20.21 ft., 2012; Photograph by Steve Johnson / UF College of Journalism and Communications

Packet Switching (Weimer Hall), detail

Packet Switching (Weimer Hall), (detail) College of Journalism and Communications, University of Florida, inkjet on polyester on panel, 177.5 ft. x 20.21 ft., 2012; Photograph by Steve Johnson / UF College of Journalism and Communications

Packet Switching project: ColladaFragmenter software, Kassel, Germany and University of Florida Public Commission

3D model in Rhino

Joelle Dietrick and I embarked on a new body of work this summer called “Packet Switching.” Inspired by her Sherwin Series images and wall paintings, and my work deconstructing and re-visualizing source code and other data, we’ve created two new software projects, as well as a series of limited edition prints, large photo installations, wall-sized paintings, and animations.

3D model in Photoshop

The full statement explains our process and intent clearly:

Packet Switching is an ongoing body of work by Joelle Dietrick and Owen Mundy that visualizes architecture as fragments affected by economic and communications systems.

The title of the series references how contemporary communications systems break digital files into smaller manageable blocks of data called packets. Each packet is then sent through a network, taking the quickest route possible, and reassembled once they reach their destination. One JPG image, for example, might be broken into several packets, each of which may travel a different path through the net, even through different cities, before being recompiled into a copy of the original file.

To reference this common process used in networked systems, we wrote custom software that deconstructs a 3D model’s source code and produces unique fragments. We further remixed these fragments using an original application created in Processing. The resulting images become limited edition prints, large photo installations, wall-sized paintings, and animations.

Our process underscores how incidental fragmentation and automation can streamline markets, but also make them vulnerable to systems failure. The use of architecture specifically points to recent real estate market volatility and considers how communication technology-enabled pursuits of profit margins alters our most basic needs.

3D model in SketchUp

The first software, that “deconstructs a 3D model’s source code and produces unique fragments,” is open source and available on Github. Essentially, the PHP software, parses a 3D COLLADA file and exports a set number of geometries, that can then be further broken down and used in an artwork or design.

The second software, which we will release soon, remixes these fragments using Processing. The video below shows an example of the whole process.

Wall painting at “Temporary Home” in Kassel, Germany

While artists-in-residence at Temporary Home, in Kassel, Germany, which coincided with Documenta13, Joelle Dietrick and I completed a wall-sized temporary painting based on the architecture from the Bauhaus School at Dessau and 2012 American color forecasts.

Packet Switching, installed at Temporary Home, Kassel, Germany

Packet Switching, installed at Temporary Home, Kassel, Germany

Packet Switching, installed at Temporary Home, Kassel, Germany

Commission at Weimer Hall at the University of Florida

Joelle and I have also received a commission to complete Packet Switching (Weimer Hall) at the University of Florida College of Journalism and Communications this fall. This will be inkjet on adhesive polyester on a large wall (approx. 177.5 ft. x 20.2 ft.). More details soon.

PaletteVisualizer

I’ve been working on a lot of projects this summer using various color palettes. Since my work involves writing programs to use these palettes in different visual outcomes, I keep wishing for an easy way to view and negotiate the lists of colors. So today I wrote a simple app to visualize a list of hexadecimal values and sort them by hue, saturation, and value (HSV). The app can be used here, and the code is open under the MIT License.

PaletteVisualizer screenshot

Thanks to Alexei Kourbatov for the color format exchange functions.

Drones at Home: Phase 1 – Gallery@Calit2

I’m collaborating with The Periscope Project (TPP) on version 2 of their “Drone Ready-Made: Fine Military Detritus” project in conjunction with the Drones at Home exhibition at Calit2 (see below). In the gallery and online, an interface I programmed, “The Drone War Did Not Take Place,” tracks a Predator drone shipping container, found on Craigslist and retrofitted by The Periscope Project as a camping apparatus, as TPP members guide it through the city of San Diego.

Drones at Home: Phase 1 – Gallery@Calit2

Their path will take them from UC San Diego, past various defense contractors and government agencies including The Space and Naval Warfare Systems Command (SPAWAR), to finally rest at TPP’s downtown location. By (re)mapping data from my Camp La Jolla Military Park project, the tracking interface reveals the connections between the physicality of TPP’s laborious gesture, and the economic and political ties between the object they push and the sites and corporations where everyone employed is implicated in the destructive impact of a permanent arms economy.

The interface will be made public during the upcoming three-day performance by The Periscope Project. It will display their location in real-time, along with images from their journey, and a twitter feed displaying news and unfiltered dialog (hashtag: #dronebox) as they trek through “the largest concentration of military facilities and defense industries in the world.”(1)

1. “San Diego Military Economic Impact Study,” San Diego Regional Chamber of Commerce, January 2007, http://www.sddt.com/files/2007_Military_Economic_Impact_Study.pdf

Poster for Drones at Home: Phase 1, Gallery@Calit2

Drones at Home
March 7–September 14, 2012

Drones at Home explores the strange allure of drones and the push for their domestication —by governments, corporations, and everyday citizens.

Phase 1
Opening Reception March 7, 2012 gallery@calit2, 5pm-7pm

Phase 2
Symposium May 11 & 12, 2012 Calit2 Auditorium, 9am-8pm

Phase 3
Opening Reception June 6, 2012 gallery@calit2, 5pm-7pm
Closing Reception September 14, 2012 gallery@calit2, 5pm-7pm

“Home” is understood at multiple scales-at the level of the individual, backyard, community, border region, and homeland. The San Diego region is featured prominently and regional issues are explored as exemplars of global phenomena. The exhibition also departs from any strict interpretation of the form that a drone must take; the project expands on the “unmanned” nature of the drone as symbolic of a larger condition–ecologies where the status of the human is called into question, distributed and embedded in a wider field of shared intelligence.

Drones at Home will be presented in three phases. Phase 1 includes an exhibition; Phase 2 consists of panels and a workshop; and Phase 3, which continues through the summer, will include the creation of new drone projects in collaboration with invited artists and research groups at Calit2. Co-curated by Sheldon Brown, Jordan Crandall, and Ricardo Dominguez, this first phase will feature the work of Matthew Battles, Trevor Paglen, The Periscope Project, Alex Rivera and Angel Nevarez, along with additional work drawn from research in the field.

Matthew Battles is a poet, writer, and co-founder of HiLobrow.com. His forthcoming books include Letter by Letter (W. W. Norton), a sentimental and natural history of writing, and a short story collection, The Sovereignties of Invention (Red Lemonade). He is a research fellow with metaLAB, an academic and creative collaborative devoted to the exploration of technology in the arts and humanities, hosted by Harvard University’s Berkman Center for Internet and Society.

Alex Rivera is a New York based digital media artist and filmmaker. His first feature film, SLEEP DEALER premiered at Sundance 2008, and won two awards, including the Waldo Salt Screenwriting Award. Rivera is a Sundance Fellow and a Rockefeller Fellow. His work, which addresses concerns of the Latino community through a language of humor, satire, and metaphor, has also been screened at The Berlin International Film Festival, New Directors/New Films, The Guggenheim Museum, PBS, Telluride, and other international venues.

Angel Nevarez is an artist, musician, and DJ. He has produced works which investigate contemporary music, dissent, and public fora, and move between the spatial simultaneity of performance and enunciation, reflecting upon the projection of political agency through transmission and song. His interests lie in the formation of mobile, performative, and discursive-based social spaces, along with the re-articulation of communicatory systems within such locales. Nevarez is also a faculty member of MIT’s Art, Culture, and Technology Program.

Trevor Paglen’s work deliberately blurs lines between science, contemporary art, journalism, and other disciplines to construct unfamiliar, yet meticulously researched ways to see and interpret the world around us. Paglen’s visual work has been exhibited at the Metropolitan Museum of Art, New York; The Tate Modern, London; The Walker Arts Center, Minneapolis; The Andy Warhol Museum, Pittsburgh; Institute for Contemporary Art, Philadelphia; The San Francisco Museum of Modern Art; Massachusetts Museum of Contemporary Art, North Adams; the 2008 Taipei Biennial; the Istanbul Biennial 2009, and numerous other solo and group exhibitions.

The Periscope Project is a space and co-operative based in downtown San Diego committed to the transdisciplinary nexus of art, architecture, and regional urban issues. Operating by the efforts of its resident practitioners; Drone Readymade represents the first discreet project (outside of The Periscope Project itself) undertaken collaboratively. The project’s primary authors are James Enos (M.Arch, NSAD, MFA UCSD, Visiting Assistant Professor, FSU), Molly Enos (M.Arch NSAD, AIA), Charles G. Miller (MFA UCSD), Keith Muller, Andrea Ngan, David Kim, Jon Barth, Jason Durr and Jay Ojeda; with key contributions from Jon Zuppan. For Drones at Home, The Periscope Project is collaborating with Owen Mundy (MFA UCSD, Assistant Professor FSU).

All gallery events are FREE and open to the public.
Please RSVP to Trish Stone, Gallery Coordinator, tstone@ucsd.edu
Media Contact: Tiffany Fox, tfox@ucsd.edu

Gallery@Calit2

Freedom for Our Files: Canvas starter (Facebook) app

I’m happy to share the code from a Facebook app I created for a workshop earlier this year.

This simple Facebook canvas application was originally demoed during the Freedom for Our Files workshop at the 2011 Art Meets Radical Openness festival in Linz, Austria. You can view and download the source code on github

The application is very simple; it creates a Facebook object, performs calls to get data belonging to the current user, then prints the data exactly as it is returned. It has examples of basic Facebook Graph API calls as well as an example of FQL (Facebook Query Language).

Freedom for Our Files: Canvas starter (Facebook) app

Stop SOPA Blackout

You might notice my site and blog looks a little, well, opaque this week. Here’s a screenshot.

Stop SOPA Blackout

I’m running a script on my site that censors all the content in order to bring attention to a law being pushed through congress right now. The SOPA (“Stop Online Piracy Act”) is a terrible piece of legislation that gives broad powers for the courts to take down sites by claims from “infringed” users. If SOPA passes as-is, it could devastate the artistic expression and livelihood of many artists, hackers, and entrepreneurs.

More information at fightforthefuture.org

You can protest the SOPA bill and install the blackout code on your site to let your visitors know what they could miss out if SOPA does pass.

Paste this code into your Tumblr themes, website, and more…

<script type="text/javascript">
  var FATLAB_Stop_SOPA = {
    color : '#000000',
    promote : true
  };

  document.write('<scr'+'ipt src="http://fffff.at/stop_sopa/blackout.js?v=1&e83a2c"></scr'+'ipt>');
</script>

New line plotter prints of I Am Unable to Fulfill Your Wish

Here are some images Ryan Boatright of Atelier Boba made while he was printing one of my network visualizations from the I Am Unable to Fulfill Your Wish series on their new line plotter. The prints arrived last week from their location in Paris and are great to see in person. The line plotter repeated so many of the lines it actually polished the surface of the paper causing the print to reflect light.

I am Unable to Fulfill Your Wish by Owen Mundy

I am Unable to Fulfill Your Wish by Owen Mundy

I am Unable to Fulfill Your Wish by Owen Mundy

I am Unable to Fulfill Your Wish by Owen Mundy

I am Unable to Fulfill Your Wish by Owen Mundy

Camp La Jolla Military Park: Creative Disturbance Through Adaption of National Park Iconography

I recently published an essay, “Camp La Jolla Military Park: Creative Disturbance Through Adaption of National Park Iconography,” in the Parsons Journal for Information Mapping (PJIM) documenting my thesis work at the University of California, San Diego. Here is the abstract for the essay:

This paper details the motivation and the method behind the creation of Camp La Jolla Military Park, a fictional national park on the current site of the University of California’s San Diego campus. Camp La Jolla Military Park borrows the iconography and language from historical battlefields as designated and protected by the U.S. Congress; the use of such iconography and language allows for the investigation, as well as consideration of the campus as a site for research and development of weapons and technology for the defense industry. The website http://camplajolla.org/ is the publicly accessible collective of the research and expression behind Camp La Jolla Military Park.

The project began by developing a data-collection system in order to record the historical, geographic, and economic ties that bind the relationships of power within the complex of military, industrial, and academic institutions in Southern California. Through appropriating the vernacular language and imagery of the National Park System the research was made public and accessible to audiences both within and outside of the protected spaces of art and academia. This writing introduces the concepts and processes of the project in order to encourage the restaging of other similar creative disturbances.

Camp La Jolla Military Park

Camp La Jolla Military Park

Camp La Jolla Military Park thumbnails

Internet service just got creepy: How to set up a wireless router with Comcast internet service

I just moved back to Florida after a one year research project in Berlin and have subscribed to Comcast broadband service. The whole experience left a bad taste in my mouth, though not because the tech showed-up 2 hours after the installation appointment window. Nor was it because he held loud personal conversations on his cell phone while he was setting up the service. No, the icky feeling is more corporate and selfish, and impedes much more into my private space than “Joe the cable guy” ever could.

Comcast made me install software on my computer in order to use their broadband.

Upon his arrival, “Joe” announced he would need access to my computer to setup broadband service. Understanding that most of the people Joe deals with might not be IT whizzes, and could manage to not be able to connect their machines without his help, I decided to let him use it rather than attempt to prove I was not a member of the usual group. After half an hour of complaining about previous customers to his friend on his cellphone, waiting for an other Comcast person to flip a switch allowing him to do his job, and multiple trips to his truck, he showed me that the internet was indeed accessible on my computer.

At this point the laptop was directly connected to the cable modem via an ethernet cable. He announced I was to follow the steps on the screen and he was out the door. The web page he had left up required me to agree to some terms, create a username and then… install software? Really? I tried to access the net without the final step but nothing doing. Unless I installed this software I was stuck. So I did it, still not believing that a company had really initiated this final invasion onto every customer’s computer. After it was done I had new bookmarks everywhere, for Comcast email, security, and some branding nonsense called “XFINITY” (I thought “X” was out with the ’90’s and “X”games?)

Comcast icons

So I thought, “OK, Comcast, you got me, hit me with your best marketing slime. Whatever, I can delete the bookmarklets you installed in my browser, just let me access the service I paid for, wirelessly, on whichever device I want.”

But this is where the relationship got really creepy. Apparently when I installed the Comcast (spyware?) on my machine, it made note of my MAC address, a unique identifier of networked machines, so that it would only allow my machine (or another machine with that MAC address) to connect to the internet. This means when I attached a wireless router to the cable modem I could connect to the wifi, but there was no internet.

Comcast welcome page

So it turns-out that Comcast is not only forcing their adware on customers, it’s also making it difficult (though not impossible) for them use more than one device. Presumably Comcast is doing this in order to circumvent sharing of services among neighbors, but the end result is that you can’t share the service between more than one device, or between roommates or spouses for that matter.

An example (albeit a geeky one): between my wife and I we have 2 laptops, 2 smartphones, and a desktop computer that all might be talking to each other or accessing the net. Comcast’s so-called internet service didn’t allow for any such geekery because it only allows one device, with the correct MAC address, to connect.

So, here’s what I did, on my Mac, with some help from my sister’s boyfriend, Tom, and a lot from Google, to get my linksys wireless router to work with Comcast internet.

  1. Confirm you can access the internet with your machine connected directly to the Comcast cable modem.
  2. Open Terminal and type (without the quotes): “ifconfig en0 | grep ether”
  3. Now disconnect your computer from the modem and connect the modem ethernet cable to your wireless router. Make sure both are plugged-in.
  4. Connect to your wireless router via the airport on your machine.
  5. Go to the following link: http://192.168.1.1
  6. Under Setup, choose DHCP as the Internet Connection Type. Save Settings.
  7. Under Setup : Mac Address Clone, enter the alpha numeric characters returned from Terminal. Save Settings.
  8. Configure your wireless router like you normally would and you are up and running.
  9. Snicker at Comcast

Linksys UI

Give Me My Data upgrade: New API, authorization, and data formats

Picture 28

No one would be surprised to learn that almost all of the user-generated content websites use our personal data to sell advertisements. In fact 97% of Google’s revenue comes from advertising.[1] That’s why it’s important these sites provide as much access as possible to the real owners of our data‐us. After all, we put it there and allow them to use it in exchange for the use of their software. Seems like a fair trade if you ask me.

A year and a half ago Facebook didn’t provide any access. That’s why I created Give Me My Data, to help users reclaim and reuse their personal data they put on Facebook.

By giving more agency to users of online systems, Give Me My Data may have already impacted the nature of online application development. In November 2010, almost a year after I launched Give Me My Data, Facebook created their own service for users to export their profile from Facebook as a series of HTML pages. Unlike Give Me My Data, the Facebook service doesn’t allow you to select which data you want or to choose custom formats to export. It also doesn’t give you options for visualization like the custom network graphs that Give Me My Data offers.

I believe their motivation originates in part with my application, likely due to the popularity of Give Me My Data, and points to the potential usefulness of similar apps. While years down the road may reveal many other online systems giving users control over their data, I see this as a positive effect where the content we create, as well as the means to share and manage it, are democratized.

Meanwhile, the above also keeps me hard at work developing the Give Me My Data project. This week I rewrote the program to use Facebook’s new OAuth authorization, which also required rewriting all of the code that fetches the data. Previously it used the REST API which is being deprecated (sometime?) in the future. I also added new data types, fixed the CSV format (which had the rows and columns mixed-up), and added the possibility to export in the JSON data format.

Finally, in the data selector, I distinguished standard data and customized data types. When I say customized, I mean that I’ve written code that mashes together more than one data table and/or addresses a specific question. For example, right now users can select from two types of network graphs and corresponding formats. One describes the user’s relationship to their friends, and the other describes the user’s relationship to their friends, as well as all their friends’ relationships to each other in various graph description languages. This is how I made the network graph image below. I’m also interested in hearing other suggestions for custom queries I might add. The project will be open source on Github soon, so even code contributions will be welcome.

Anyway, please try out the new version. You may have to delete the app from your allowed applications and then re-authorize it if you’ve used it before. As usual, you can provide feedback on the application page, and you can also contact me on Twitter via @givememydata.

Facebook mutual friends network graph

[1] “Google Financial Tables for Quarter ending June 30, 2009” Retrieved October 13, 2010

Give Me My Data 2.0 advances to 2nd round of Rhizome Commission voting

Picture 13

I just learned the Give Me My Data 2.0 proposal I put together with Dr. Phil Steinberg has advanced to the second stage of 2011 Rhizome Commission voting. Give Me My Data 2.0 is an open source web application that exports your user data from any crowdsourcing website in multiple, reusable formats.

I created Give Me My Data while working on Automata, a project which visualizes powerful relationships and which also made it to the second round of the Rhizome Commissions two years ago.

Please VOTE for Give Me My Data if you are a Rhizome member!

Freedom for Our Files: Code and Slides

A two-day workshop, with both technical hands-on and idea-driven components. Learn to scrape data and reuse public and private information by writing custom code and using the Facebook API. Additionally, we’ll converse and conceptualize ideas to reclaim our data literally and also imagine what is possible with our data once it is ours!

Here are the slides and some of the code samples from the Freedom for Our Files (FFOF) workshop I just did in Linz at Art Meets Radical Openness (LiWoLi 2011).


Download the slides (PDF)

The first one is a basic scraping demo that uses “find-replace” parsing to change specific words (I’m including examples below the code)

<?php

/*	Basic scraping demo with "find-replace" parsing
 *	Owen Mundy Copyright 2011 GNU/GPL */

$url = "http://www.bbc.co.uk/news/";	// 0. url to start with

$contents = file_get_contents($url);	// 1. get contents of page in a string

					// 2. search and replace contents
$contents = str_replace(		// str_replace(search, replace, string)
			"News",					
			"<b style='background:yellow; color:#000; padding:2px'>LIES</b>",
			$contents);

print $contents;			// 3. print result

?>

Freedom for Our Files: Code and Slides

Web scraper code for the BBC website using find and replace

Basic scraping demo with “foreach” parsing

<?php

/*	Basic scraping demo with "foreach" parsing
 *	Owen Mundy Copyright 2011 GNU/GPL */
 
$url = "http://www.bbc.co.uk/news/";	// 0. url to start with

$lines = file($url);			// 1. get contents of url in an array

foreach ($lines as $line_num => $line) 	// 2. loop through each line in page
{		
					// 3. if opening string is found
	if(strpos($line, '<h2 class="top-story-header ">')) 	
	{
		$get_content = true;	// 4. we can start getting content
	}
	
	if($get_content == true)
	{
		$data .= $line . "\n";	// 5. then store content until closing string appears
	}

	if(strpos($line, "</h2>")) 	// 6. if closing HTML element found
	{
		$get_content = false;	// 7. stop getting content
	}
}

print $data;				// 8. print result

?>

Web scraper code for the BBC website using a foreach loop

Basic scraping demo with “regex” parsing

<?php

/*	Basic scraping demo with "regex" parsing
 *	Owen Mundy Copyright 2011 GNU/GPL */
 
$url = "http://www.bbc.co.uk/news/";		// 0. url to start with

$contents = file_get_contents($url);		// 1. get contents of url in a string
											
						// 2. match title
preg_match('/<title>(.*)<\/title>/i', $contents, $title);

print $title[1];				// 3. print result

?>

Web scraper code for the BBC website using a regular expression to find the title

Basic scraping demo with “foreach” and “regex” parsing

<?php

/*	Basic scraping demo with "foreach" and "regex" parsing
 *	Owen Mundy Copyright 2011 GNU/GPL */

// url to start
$url = "http://www.bbc.co.uk/news/";

// get contents of url in an array
$lines = file($url);

// look for the string
foreach ($lines as $line_num => $line) 
{	
	// find opening string
	if(strpos($line, '<h2 class="top-story-header ">')) 
	{
		$get_content = true;
	}
	
	// if opening string is found 
	// then print content until closing string appears
	if($get_content == true) 
	{
		$data .= $line . "\n";
	}

	// closing string
	if(strpos($line, "</h2>")) 
	{
		$get_content = false;
	}
}

// use regular expressions to extract only what we need...

// png, jpg, or gif inside a src="..." or src='...' 
$pattern = "/src=[\"']?([^\"']?.*(png|jpg|gif))[\"']?/i";
preg_match_all($pattern, $data, $images);

// text from link
$pattern = "/(<a.*>)(\w.*)(<.*>)/ismU";
preg_match_all($pattern, $data, $text);

// link
$pattern = "/(href=[\"'])(.*?)([\"'])/i";
preg_match_all($pattern, $data, $link);

/* 
// test if you like
print "<pre>";
print_r($images);
print_r($text);
print_r($link);
print "</pre>";
*/

?>

<html>
<head>
<style> 
body { margin:0; } 
.textblock { position:absolute; top:600px; left:0px; }
span { font:5.0em/1.0em Arial, Helvetica, sans-serif; line-height:normal; 
background:url(trans.png); color:#fff; font-weight:bold; padding:5px } 
a { text-decoration:none; color:#900 }
</style>
</head>
<body>
<img src="<?php print $images[1][0] ?>" height="100%"> </div>
<div class="textblock"><span><a href="<?php print "http://www.bbc.co.uk".$link[2][0] ?>"><?php print $text[2][0] ?></a></span><br>
</div>
</body>
</html>

And the example, which presents the same information in a new way…

Web scraper code for the BBC website using a regular expression

Advanced scraping demo with “regex” parsing. Retrieves current weather in any city and colors the background accordingly. The math below for normalization could use some work.

<?php

/*	Advanced scraping demo with "regex" parsing. Retrieves current 
 * 	weather in any city and colors the background accordingly. 
 *	The math below for normalization could use some work.
 *	Owen Mundy Copyright 2011 GNU/GPL */

?>

<html>
<head>
<style> 
body { margin:20; font:1.0em/1.4em Arial, Helvetica, sans-serif; } 
.text { font:10.0em/1.0em Arial, Helvetica, sans-serif; color:#000; font-weight:bold; } 
.navlist { list-style:none; margin:0; position:absolute; top:20px; left:200px }
.navlist li { float:left; margin-right:10px; }
</style>
</head>

<body onLoad="document.f.q.focus();">

<form method="GET" action="<?php print $_SERVER['PHP_SELF']; ?>" name="f">

	<input type="text" name="q" value="<?php print $_GET['q'] ?>" />
	<input type="submit" />

</form>

<ul class="navlist">
	<li><a href="?q=anchorage+alaska">anchorage</a></li>
	<li><a href="?q=toronto+canada">toronto</a></li>
	<li><a href="?q=new+york+ny">nyc</a></li>
	<li><a href="?q=london+uk">london</a></li>
	<li><a href="?q=houston+texas">houston</a></li>
	<li><a href="?q=linz+austria">linz</a></li>
	<li><a href="?q=rome+italy">rome</a></li>
	<li><a href="?q=cairo+egypt">cairo</a></li>
	<li><a href="?q=new+delhi+india">new delhi</a></li>
	<li><a href="?q=mars">mars</a></li>
</ul>

<?php

// make sure the form has been sent
if (isset($_GET['q']))
{
	// get contents of url in an array
	if ($str = file_get_contents('http://www.google.com/search?q=weather+in+'
						. str_replace(" ","+",$_GET['q'])))
	{
		
		// use regular expressions to extract only what we need...
		
		// 1, 2, or 3 digits followed by any version of the degree symbol 
		$pattern = "/[0-9]{1,3}[º°]C/";
		// match the pattern with a C or with an F
		if (preg_match_all($pattern, $str, $data) > 0)
		{
			$scale = "C";
		}
		else
		{
			$pattern = "/[0-9]{1,3}[º°]F/";
			if (preg_match_all($pattern, $str, $data) > 0)
			{
				$scale = "F";
			}
		}
		
		// remove html
		$temp_str = strip_tags($data[0][0]);
		// remove everything except numbers and points
		$temp = ereg_replace("[^0-9..]", "", $temp_str);
		
		if ($temp)
		{
			
			// what is the scale?
			if ($scale == "C"){
				// convert ºC to ºF
				$tempc = $temp;
				$tempf = ($temp*1.8)+32;
			}
			else if ($scale == "F")
			{
				// convert ºF to ºC
				$tempc = ($temp-32)/1.8;
				$tempf = $temp;
			}
			// normalize the number
			$color = round($tempf/140,1)*10;
			// cool -> warm
			// scale -20 to: 120
			$color_scale = array(
					'0,  0,255',
					'0,128,255',
					'0,255,255',
					'0,255,128',
					'0,255,0',
					'128,255,0',
					'255,255,0',
					'255,128,0',
					'255,  0,0'
					);	
		
?>

<style> body { background:rgb(<?php print $color_scale[$color] ?>) }</style>
<div class="text"><?php print round($tempc,1) ."&deg;C " ?></div>
<?php print round($tempf,1) ?>&deg;F

<?php
		
		}
		else 
		{
			print "city not found";	
		}
	}
}
?>

</body>
</html>

Freedom for Our Files: Code and Slides

Freedom for Our Files: Code and Slides

Freedom for Our Files: Code and Slides

Freedom for Our Files: Code and Slides

For an xpath tutorial check this page.

For the next part of the workshop we used Give Me My Data to export our information from Facebook in order to revisualize it with Nodebox 1.0, a Python IDE similar to Processing.org. Here’s an example:

NodeBox

Update: Some user images from the workshop. Thanks all who joined!

Mutual friends network graph, cropped

Mutual friends network graph

Mutual friends (using Give Me My Data and Graphviz) by Rob Canning

Identica network graph drawn with Graphviz sfdp

identi.ca network output (starting from my username (claude) with depth 5, rendered to svg with ‘sfdp’ from graphviz) by Claude Heiland-Allen

Freedom for Our Files workshop

Freedom for Our Files workshop

Convert NTSC video to PAL with smooth motion

When converting NTSC digital video to PAL the pixel aspect ratio needs to change from 720 x 480 (NTSC) to 720 x 576 (PAL). Depending on your project the more important problem is the transition from 29.97 (NTSC) frames per second to 25 (PAL).

Video settings that do not match

I found Final Cut Pro and QuickTime both convert 29.97 to 25 frames per second by cutting the five extra frames to make it fit. This results in a loss of temporal resolution, making motion in the footage jerk and skip because the frames which created the illusion of motion are missing.

There are a few commercial applications that can convert NTSC to PAL with smooth motion, but I followed advice on this forum which suggested using Compressor for the standards conversion:

  1. Export an NTSC Quicktime movie from Final Cut Pro without compression
  2. In Compressor, select a DV PAL preset
  3. Turn on Frame controls and set resizing and retiming to “better” or “best.”
  4. Run Compressor. This took >3 hours for 12 minutes of uncompressed footage.

This should give you a 720 x 576 (PAL CCIR 601) with 25 frames per second. Finally, in DVD Studio Pro make sure you choose PAL before you import any footage, and leave all the regions selected which is the default.

Video export settings

UNIX: List open files

Picture 3


Can’t eject a CD or unmount an external hard drive on your mac because of this error: The disc is in use and could not be ejected. Try quitting applications and try again.?

This UNIX command reports a list of all open files and applications that opened them. Open Terminal and replace the name of your volume below to test.

$ lsof | grep /Volumes/media/

Thanks

Addendum: Here’s an even more helpful command: eject the disk with UNIX when the GUI won’t allow it.

$ diskutil eject [Mount Point|Disk Identifier|Device Node]

Oh, and a final tip nestled in this addition: If you have a space in the name (for example you had two disks mounted named “backup” and OSX named the second one to mount “backup 1”) then you can easily reference the name (or any file or directory name with a space) with a backslash which “escapes” the character. Typing the first few characters and then type the tab key will do it automatically.

$ diskutil eject /Volumes/backup\ 1/

Network graph grouping: A small art world

This “Mutual friends network graph” created with Nodebox using data I exported with Give Me My Data contains 540 “Facebook friends” and their connections to each other. When the graph renders it attempts to position people who have lots of connections closer together. With this you can see groups unfold based on your own social networks. Since I have spent more time in academia than I have at specific jobs my “clusters” are based mostly on my academic history.

You can also see that there are a lot of connections between my high school and where I did my undergraduate study, which is based on the fact they are located very close to each other, so friends from high school also chose the same university or town to live in. There are also a lot of interconnections between Indiana University where I did my undergrad, the University of California, San Diego, where I did graduate study, and Florida State University, where I teach now. This is probably due to the fact that my connections are all within a given field, in my case visual arts, and points to the often expressed notion that “the art world is actually very small.”

Facebook mutual friends network graph, grouped into clusters

Random Hacks of Kindness (RHoK) and Google Person Finder

Last weekend I took part in Random Hacks of Kindness an international hackathon dedicated to creating useful systems to respond to critical global challenges. I met with other programmers at the Betahaus in Berlin and worked with Tim Schwartz and Mikkel Gravgaard on Google Person Finder a searchable database of missing persons that helps people find loved ones during disasters. It was used during the 2010 Haiti and Chilean Earthquakes and is developed by volunteers and employees of Google.

Picture 21

Photo by Flickr user rhokberlin

Random Hacks of Kindness

Photo by Flickr user nblr

Random Hacks of Kindness

Photo by Flickr user nblr

Give Me My Data and exporting mutual friends

On the one-year anniversary of the beginning of Give Me My Data I’m very happy to announce that you can now export your friends and your mutual friends from facebook using two new formats. Both of the data formats are geared towards making graphs by displaying objects and their relationships. Needless to say, this is the most often requested feature since the official beta launch in April 2010. See below for more information

The DOT language

DOT is a plain text graph description language and can be rendered using a variety of layout applications like Graphviz or Tulip.

This example (saved as a plain text file with the .dot extension)

graph G
{
	a -- b -- c;
	b -- d;
}

Produces something like this

Mutual friends network exported as a DOT file

Python / Nodebox 1.0

NodeBox logo

The other file format is also for visualizing relationships. You can copy and paste the contents into a plain text file saved with a .py extension and open it in Nodebox, a Mac application that uses Python to create 2D visuals. Learn more about creating graphs in Nodebox.

Here’s an example file. My mutual friends exported from Facebook…

Facebook mutual friends network graph

Plutonian Striptease VIII: Owen Mundy

Originally published in Plutonian Striptease, a series of interviews with experts, owners, users, fans and haters of social media, to map the different views on this topic, outside the existing discussions surrounding privacy.

PS: Social networks are often in the news, why do you think this is?

OM: Assuming “social networks” refers to the online software, application programming interfaces (APIs), and the data that constitutes sites like MySpace, Facebook, and Twitter, I feel its popular to discuss them in the news for many reasons.

Online applications that enable enhanced connectivity for individuals and other entities are relatively new and there is an apparent potential for wealth through their creation and the connections they enable. News organizations are businesses, so they naturally follow the money, “reporting” on topics which are considered worthwhile to advertisers who buy space in their pages, pop-ups, and commercial breaks.

Additionally, the public is still grappling with the ability for online software to collect and distribute data about them, both with their permission and through clandestine means at once. Most users of social networking software don’t understand the methods or potential for behavior manipulation in these user interfaces and therefore are wary of what they share. Other users seem to be more care-free, making many private details from their lives public.

Finally, online social networking software is still evolving, so it’s difficult for users to establish a consensus about best practices. I believe the accelerating functionality of web 2.0 software will continue to complicate how we feel about online social networks for much longer.

PS: In what way do they differ from older forms of communication on the Internet?

OM: If web1.0 consisted of static pages, web2.0 is made-up of dynamic information, generated by the millions of users accessing the web through personal computers and mobile devices. This rapid rise in user-generated content has been made possible by the development of online applications using a myriad of open source programming languages. Sites like youtube.com (launched 2005 and written primarily in Python) and Facebook.com (2004, PHP) which consist entirely of content contributed by users, store information in databases allowing for fast searching, sorting, and re-representation. Initially, the web consisted of information and we had to sift through it manually. Web2.0 allows for the growth of a semantic web and possibilities for machines to help us describe, understand, and share exponential amounts of data through tags, feeds, and social networks.

PS: Who is ultimately responsible for what happens to the data you upload to social networks?

OM: Obviously users are responsible for deciding what information they publish online. Still, Facebook’s “Recommended Privacy Settings” should emphasize more not less. While their privacy settings always seem to be a work in progress. One thing they do consistently is default to less privacy overall, thus more sharing of your information on their site. For a website that depends on user-generated content the motivation to encourage sharing is clear enough. Still, why do they use the word “privacy” if they’re not actually embracing the idea?

I honestly feel that all software that accepts user input, credit cards and phone companies, should be bound by strict written rules preventing them from sharing my information with advertising companies or the government. It seems like a basic human right to me. If there are laws preventing me from downloading and sharing copyrighted music then there should be laws protecting my intellectual property as well.

PS: Do you read Terms of Use or EULA’s and keep up to date about changes applied to them?

OM: Only when curious or suspicious. They’re usually intentionally full of so much legalese that I don’t bother torturing myself. But as an artist and programmer, I have an interest in sharing my information in public space because I benefit from its appreciation. Perhaps a more accurate answer to this question would come from someone who doesn’t have this interest.

PS: Do you think you’ve got a realistic idea about the quantity of information that is out there about you?

OM: Yes I do. I am definitely conscious of the information I share. In addition I also research methods of surveillance and incorporate that knowledge into my art practice. So while I haven’t seen the visualization that determines the likelihood that my grandmother is a terrorist threat, it’s guaranteed that one is possible with a few clicks and some multi-million dollar defense contractor dataveillance tool. This is true for any human being through aggregation of credit card records, travel information, political contributions, and what we publish online.

PS: How do you value your private information now? Do you think anything can happen that will make you value it differently in the future?

OM: It’s important to me to situate my art practice in public space where it can provoke discussion for all audiences. But yes, I do intentionally avoid distributing dorky pictures of my mountain bike adventures. Seriously though, I’ve been watching the news. I can say that I’m definitely alarmed by the post-911 surveillance on U.S. citizens.

PS: How do you feel about trading your personal information for online services?

OM: It depends on the service. We all have to give up something in order to use these tools. For example, without telling Google Maps that I’m interested in Mexican restaurants in Williamsburg, I might never find Taco Chulo. This continual paradox in making private information public is somewhat rendered void if the sites we use actually protect our information, but it is more likely that everything we say and do online is used to some degree to enhance and advertisements. Here’s another example, 97% of Google’s revenue comes from advertising, which should suggest that while they produce software, their ultimate goal is to appeal to advertisers.[1]

PS: What do you think the information gathered is used for?

OM: I have a background in interface design and development so I know how great it is to use web stats to see where users are clicking. If traffic is not moving in the direction that you want then you can make specific buttons more prevalent.

I can only imagine what a company like Google does with the data they gather through their analytics tools. The fact that a government could access this information is scary when you think of the actions of past fascist states. The amount of control a government could levy through a combination of deep packet searching and outrightly ignoring human rights is staggering.

PS: Have you ever been in a situation where sharing information online made you uncomfortable? If so, can you describe the situation?

OM: Definitely. Sharing financial information online always causes a little anxiety. One of my credit cards has been re-issued three times now due to “merchant databases being hacked.”

PS: What is the worst case scenario, and what impact would that have on an individual?

OM: I just moved to Berlin so I’m looking at the history of this place quite a bit. This is relevant because, during the Cold War, before Germany was reunited, the German Democratic Republic (GDR) Ministry for State Security (MfS) or ‘Stasi’ is believed to have hired, between spies and full- and part-time informants, one in every 6.5 East German citizens to report suspicious activities.[2] That’s millions of people. At this moment, the ratio of people entering data on Facebook to non-members is one in fourteen for the entire world.[3] We have probably the most effective surveillance machine in the history of mankind.

PS: Nowadays, most of the “reading” of what is written online is done by machines. Does this impact your idea of what is anonymity and privacy?

OM: Well, it’s not surprising the interview has come to this point, since I keep referencing the multitude of methods of computer-controlled digital surveillance. It’s true that machines have replaced humans for remedial work. For example: searching text strings for suspicious statements. But the ultimate danger to my privacy is only enhanced by machines. The real problem is when companies that I trust with my data decide to share it with corporations or governments that engage in behavior control.

PS: Can a game raise issues such as online privacy? And if so, what would you like to see in such a game?

OM: I find this question to be intentionally leading. Perhaps its because I’m generally optimistic and come from farmers, so I assume anything is possible? Not being a gamer though, I can tell you honestly that yes, it is possible, but you will have some challenges if you intend to reach an audience that doesn’t already agree with you. Reaching non-gamers who don’t already feel the same will be even tougher.

Games are generally immersive; you are either playing or your not. The biggest challenge you may have is reaching non-gamers, because they don’t generally invest large amounts of time in games for enjoyment. Try to find ways to highlight complexity and prompt discussion regardless of how long users play, and make this clear from the outset.

Finally, in politically-motivated cultural production it’s important to appeal to an audience first, and let them come to the issues on their own. Who would sit through a film knowing the twist at the end? Especially a conclusion intended to spur critical thinking and action, which is of course the goal.

[1] “Google Financial Tables for Quarter ending June 30, 2009” Retrieved October 13, 2010
[2] Koehler, John O. (2000). Stasi: the untold story of the East German secret police. Westview Press. ISBN 0813337445.
[3] “Facebook Statistics” Retrieved October 14, 2010

Facebook’s recommended privacy settings should emphasize more not less

Facebook’s “Privacy Settings” always seem to be a work in progress. One thing they do consistently is default to less privacy overall, thus more sharing of your information on their site. For a website that depends on user-generated content the motivation to encourage sharing is clear enough. Still, why do they use the word “privacy” if they’re not actually embracing the idea?

For example, a recent update introduces a table with degrees of privacy from less to more (left to right). Types of data are listed in rows, while access is shown in the columns, with Everyone to Friends Only, again left to right.

Facebook privacy settings showing more sharing

Curious about what Facebook “Recommended” settings were, I clicked and am sharing the screenshot below. I am not surprised to see that they wish me to open-up all content I generate; status messages, posts, images, etc. and discourage allowing anyone I don’t know to comment on posts (probably as spam prevention).

Facebook privacy settings showing less sharing

I have been thinking about privacy quite a bit this week, developing ideas for what next to do with Give Me My Data, and providing an interview about social media for Naked on Pluto (along with the likes of Marc Garrett and Geert Lovink). Plus I went to see the “geek hero story” The Social Network at the Babylon Cinema last night.

Anyway, after all this thinking about Facebook’s past, I’m curious about its future, and how it will continue to try to hold on to the #1 social networking website position that Friendster and MySpace lost so quickly. The API, games, etc could be expected, but the Facebook Connect tools that are so prevalent now, even on Yelp, a site I figured could make it without schlepping, were a surprise.

Facebook Connect, a jquery “widget” that allows you to login to other websites using your Facebook ID, is clever and eerie at once. It allows Facebook to track you when you are not even on their site, and make sure you stay loyal. If that sounds sinister, well it is. What other purpose could there be for making available a service with the single purpose of mediating every interaction or bit of content you add to the web? It seems at first like OpenID, and it is, except that its run by a multi-billion dollar social media corporation.

How to install Scrapy with MacPorts (full version)

MacPorts logo

+

MacPorts logo

Here is a step-by-step explaining how I got Scrapy running on my MacBook Pro 10.5 using MacPorts to install Python and all required libraries (libxml2, libxsit, etc.). The following has been tested on two separate machines with Scrapy .10.

Many thanks to users here who shared some helpful amendments to the default installation guide. My original intention was to post this at stackoverflow, but their instructions discourage posting issues that have already been answered so here it is…

1. Install Xcode with options for command line development (a.k.a. “Unix Development”). This requires a free registration.

2. Install MacPorts

3. Confirm and update MacPorts

$ sudo port -v selfupdate

4. “Add the following to /opt/local/etc/macports/variants.conf to prevent downloading the entire unix library with the next commands”

+bash_completion +quartz +ssl +no_x11 +no_neon +no_tkinter +universal +libyaml -scientific

5. Install Python

$ sudo port install python26

If for any reason you forgot to add the above exceptions, then cancel the install and do a “clean” to delete all the intermediary files MacPorts created. Then edit the variants.conf file (above) and install Python.

$ sudo port clean python26

6. Change the reference to the new Python installation

If you type the following you will see a reference to the default installation of Python on MacOS 10.5 (Python2.5).

$ which python

You should see this

/usr/bin/python

To change this reference to the MacPorts installation, first install python_select

$ sudo port install python_select

Then use python_select to change the $ python reference to the Python version installed above.

$ sudo python_select python26

UPDATE 2011-12-07: python_select has been replaced by port select so…

To see the possible pythons run

port select --list python

From that list choose the one you want and change to it e.g.

sudo port select --set python python26

Now if you type

$ which python

You should see

/opt/local/bin/python

which is a symlink to

/opt/local/bin/python2.6

Typing the below will now launch the Python2.6 shell editor (ctl + d to exit)

$ python

7. Install required libraries for Scrapy

$ sudo port install py26-libxml2 py26-twisted py26-openssl py26-simplejson

Other posts recommended installing py26-setuptools but it kept returning with errors, so I skipped it.

8. “Test that the correct architectures are present:

$ file `which python`

The single quotes should be backticks, which should spit out (for intel macs running 10.5):”

/opt/local/bin/python: Mach-O universal binary with 2 architectures
/opt/local/bin/python (for architecture i386): Mach-O executable i386
/opt/local/bin/python (for architecture ppc7400): Mach-O executable ppc

9. Confirm libxml2 library is installed (those really are single quotes). If there are no errors it imported successfully.

$ python -c 'import libxml2'

10. Install Scrapy

$ sudo /opt/local/bin/easy_install-2.6 scrapy

11. Make the scrapy command available in the shell

$ sudo ln -s /opt/local/Library/Frameworks/Python.framework/Versions/2.6/bin/scrapy /usr/local/bin/scrapy

One caveat for the above, on a fresh computer, you might not have a /usr/local/bin directory so you will need to create it before you can run the above to create the symlink.

$ sudo mkdir /usr/local/bin

13. Finally, type either of the following to confirm that Scrapy is indeed running on your system.

$ python scrapy

$ scrapy

A final bit… I also installed ipython from Macports for use with Scrapy

sudo port install py26-ipython

Make a symbolic link
sudo ln -s /opt/local/bin/ipython-2.6 /usr/local/bin/ipython

An article on ipython
http://onlamp.com/pub/a/python/2005/01/27/ipython.html

ipython tutorial
http://ipython.scipy.org/doc/manual/html/interactive/tutorial.html

Setup Macports Python and Scrapy successfully

MacPorts logo

“Scrapy is a fast high-level screen scraping and web crawling framework, used to crawl websites and extract structured data from their pages. It can be used for a wide range of purposes, from data mining to monitoring and automated testing.”

But, it can be a little tricky to get running…

Attempting to install Scrapy on my MBP with the help of this post I kept running into errors with the libxml and libxslt libraries using the Scrapy documentation.

I wanted to try to let Macports manage all the libraries but I had trouble with it referencing the wrong installation of Python. I began with three installs:

  1. The default Apple Python 2.5.1 located at: /usr/bin/python
  2. A previous version I had installed located: /Library/Frameworks/Python.framework/Versions/2.7
  3. And a Macport version located: /opt/local/bin/python2.6

My trouble was that:

$ python

would always default to the 2.7 when I needed it to use the Macports version. The following did not help:

$ sudo python_select python26

I even removed the 2.7 version which caused only an error.

I figured out I needed to change the default path to the Macports version using the following:

$ PATH=$PATH\:/opt/local/bin ; export PATH

And then reinitiate the ports, etc.

Finally, I was not able to reference the scrapy-ctl.py file by default through these instructions so I had to reference the scrapy-ctl.py file directly

/opt/local/Library/Frameworks/Python.framework/Versions/2.6/bin/scrapy-ctl.py

UPDATE

A quick addendum to this post with instructions to create the link, found on the Scrapy site (#2 and #3).

Starting with #2, “Add Scrapy to your Python Path”

sudo ln -s /opt/local/Library/Frameworks/Python.framework/Versions/2.6/bin/scrapy-ctl.py /opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/scrapy

And #3, “Make the scrapy command available”

sudo ln -s /opt/local/Library/Frameworks/Python.framework/Versions/2.6/bin/scrapy-ctl.py /usr/local/bin/scrapy

How to easily set up a campaign finance database (well, kind of) or Make Python work with MAMP via MySQLdb

Picture 15

I’ve been trying for a few hours to run a Python script from The Sunlight Foundation Labs which downloads (and updates) a campaign finance database from the Center for Responsive Politics. See their original post for more information.

In the process of getting this working I accidentally broke a working copy of MySQL and overwrote a database installed on my MBP (which I had stupidly not backed-up since last year). FYI, you can rebuild any MySQL database with the original .frm, .MYD, and .MYI files if you 1. Recreate the database in the new install of MySQL and 2. Drag the files into the mysql data folder.

I struggled quite a bit getting Python to work with MySQL via MySQLdb. I’m documenting some of the headaches and resolutions here in case they are useful. I’ve tried to include error messages for searches as well.

The Sunlight Foundation instructions require Python and MySQL, but don’t mention you have to have already wrestled with the madness involved in installing Django on your machine. Here is what I did to get it working on my MacBook Pro Intel Core 2 Duo. I’ve included their original instructions with my own (and a host of others).

Instructions

  1. Install MAMP.

    While I had working installations of MySQL and Python (via installers on respective sites), I couldn’t get Python to connect to MySQL via MySQLdb. I decided to download and try MAMP for a clean start.

  2. Install XCode

    Past installs are available on Apple Developer website.

  3. Install setuptools

    Required for the MySQLdb driver. Remove the .sh extension from the filename (setuptools-0.6c11-py2.7.egg.sh) and in a shell:

    ~$ chmod +x setuptools-0.6c11-py2.7.egg
    ~$ ./setuptools-0.6c11-py2.7.egg

  4. Install the MySQLdb driver

    After downloading and unzipping, from the directory:

    ~$ python setup.py build
    ~$ sudo python setup.py install

    Continue following the advice of this post to the end How to install Django with MySQL on Mac OS X.

    I also followed another piece of advice in Python MySQL on a Mac with MAMP to change the mysql_config.path from:

    /usr/local/mysql/bin/mysql_config

    to

    /Applications/MAMP/Library/bin/mysql_config

    Especially useful is his test script for making sure that Python is indeed accessing MySQL.

  5. Create a symbolic link between Python and MySQL in MAMP

    This is required in order to use a socket to connect to the MySQL. See How to install MySQLdb on Leopard with MAMP for more information.

    ~$ sudo ln -s /Applications/MAMP/tmp/mysql/mysql.sock /tmp/mysql.sock

  6. Create a directory and put the two Python files in it.
  7. Modify the top of the sun_crp.py file to set certain parameters–your login credentials for the CRP download site and your MySQL database information.
  8. Install pyExcelerator

    Error: ImportError: No module named pyExcelerator

    I had to install this module next.

  9. Comment out multiple lines

    Error: NameError: name 'BaseCommand' is not defined

    In download.py comment out the following:

    The line: from django.core.management.base import BaseCommand, CommandError

    Everything from class CRPDownloadCommand(BaseCommand): to the end of the document.

  10. From the command line, run the script by typing, from the proper directory: Python sun-crp.py.
  11. It will take several hours to download and extract the data, especially the first time it’s run. But after that, you’re good to go.

Recent and ongoing projects

Howdy, it’s been awhile since I last shared news about recent and ongoing projects. Here goes.

You Never Close Your Eyes Anymore at AC Direct

1. You Never Close Your Eyes Anymore

You Never Close Your Eyes Anymore is an installation that projects moving US Geological Survey (USGS) satellite images using handmade kinetic projection devices.

Each device hangs from the ceiling and uses electronic components to rotate strips of satellite images on transparency in front of an LED light source. They are constructed with found materials like camera lenses and consumer by-products and mimic remote sensing devices, bomb sights, and cameras in Unmanned Aerial Vehicles.

The installation includes altered images from various forms of lens-based analysis on a micro and macro scale; land masses, ice sheets, and images of retinas, printed on reflective silver film.

On display now until July 31 at AC Institute 547 W. 27th St, 5th Floor
Hours: Wed., Fri. & Sat.: 1-6pm, Thurs.: 1-8pm

New video by Asa Gauen and images
http://owenmundy.com/site/close_your_eyes

2. Images and video documentation of You Never Close Your Eyes Anymore will also be included in an upcoming Routledge publication and website:

Reframing Photography: Theory and Practice
by Rebekah Modrak, Bill Anthes
ISBN: 978-0-415-77920-3
Publish Date: November 16th 2010
http://www.routledge.com/books/details/9780415779203/

Give Me My Data logo

3. Give Me My Data launch

Give Me My Data is a Facebook application designed to give users the ability to export their data out of Facebook for any purpose they see fit. This could include making artwork, archiving and deleting your account, or circumventing the interface Facebook provides. Data can be exported in CSV, XML, and other common formats. Give Me My Data is currently in public-beta.

Website
http://givememydata.com/

Facebook application
http://apps.facebook.com/give_me_my_data/

The New York Times logo

4. Give Me My Data was also covered recently by the New York Times, BBC, TechCrunch, and others:

Facebook App Brings Back Data by Riva Richmond, New York Times, May 1, 2010
http://gadgetwise.blogs.nytimes.com/2010/05/01/facebook-app-brings-back-data/

Picture 6

5. yourarthere.net launch

A major server and website upgrade to the yourarthere.net web-hosting co-op for artists and creatives. The new site allows members of the community to create profiles and post images, tags, biography, and events. In addition to the community aspect, yourarthere.net is still the best deal going for hosting your artist website.

Website
http://yourarthere.net

More images
http://owenmundy.com/site/design_yourarthere_net

Portrait from The Americans

6. The Americans

The Americans is currently on view at the Northwest Florida State College in Niceville, FL. It features a new work with the same title.

More images
http://owenmundy.com/site/the-americans

Oblique view of a schematic

7. Your Art Here billboard hanger

I recently designed a new billboard hanging device and installed it in downtown Bloomington, IN with the help of my brother Reed, and wife Joelle Dietrick.

Stay tuned here for news about Your Art Here and the new billboard by Joelle Dietrick.
http://www.facebook.com/pages/Your-Art-Here/112561318756736

Sitemap of lockheedmartin.com, drawn in red

8. Finally, moving to Berlin for a year on a DAAD fellowship to work on some ongoing projects, including Automata.

More images
https://owenmundy.com/blog/2010/07/new-automata-sitemaps/

I’ll be giving a paper about Automata at the upcoming ISEA2010 conference in Ruhr, Germany.
http://www.isea2010ruhr.org/conference/tuesday-24-august-2010-dortmund

Many thanks to Chris Csikszentmihályi, Director of the Center for Future Civic Media http://civic.mit.edu/ , for inviting me to the MIT Media Lab last August to discuss the project with his Computing Culture Group: http://compcult.wordpress.com/

Schematic for You Never Close Your Eyes Anymore

“Open sourcing” the schematic for the electronic components for You Never Close Your Eyes Anymore.

Picture 5

Products:

RBBB boards (Arduino clone)
custom-designed circuits
– female headers
– TIP31 transistor
– 6-wire Unipolar Stepper motor (48 step Nippon Electric Pulse Motor)
– ULN2803A Darlington Array
– hook-up wire
– various resistors
– LEDs
used camera lenses
aluminum “flat bar”
hose clamps
rubber wine corks
various mounting hardware

New yourarthere.net website is live

After 4 months the new yourarthere.net website and member-run content management system is now live. Thanks to Braylin and Brittany Morales, Beth Lee, and Chris Cumbie for all their hard work.

The site is valid XHTML/CSS and runs on PHP/MySQL using the Codeigniter framework. All the details from our research from inception onward are archived here.

This site is based around the idea that members should have control of the content on the website. Every member has a profile where they can add images, text, tags, and events to promote their artwork or group. Members can create a new profile for every domain they host with yourarthere.nets.

Picture 6

Picture 8

Hello World

Considering sharing the source code behind Give Me My Data on GitHub. Looks like its great for archiving, improving, and sharing…

Posted in code