Showing posts sorted by relevance for query google apps. Sort by date Show all posts
Showing posts sorted by relevance for query google apps. Sort by date Show all posts

Saturday, June 1, 2013

Google Apps Bulk Delete Users Script

Google Apps has a bulk account creation tool, but nothing for bulk deleting accounts. I had previously written something in Python to bulk delete accounts from a text file, but it was time to create something web-based. This will only work if you have the Domain API enabled, which means that you'll have to enable it in your Google Apps for Education Admin console.

Just a note, though, before deleting users you may want to direct them to the Data Liberation tools for downloading their data.

The actual script is in Google Apps Script. You can see it by visiting Google Apps Delete Users, or create your own copy at script.google.com using the source code below.

Let me know if this works for you, or if you have suggestions for improvements.


 function doGet() {  
 // get the user's credentials for their Google Apps account  
  var user = Session.getEffectiveUser().getUserLoginId()  
  var domain = UserManager.getDomain();  
  var welcome = "You are running this script as " + user + " on the domain " + domain;  
 // set up the user interface  
  var app = UiApp.createApplication().setTitle('Delete Google Apps Users by MisterHay');  
  app.add(app.createLabel(welcome));  
  app.add(app.createHTML("<br>Make sure you have enabled the Provisioning API (support.google.com/a/bin/answer.py?hl=en&answer=60757).<br>This script will delete Google Apps user accounts that you paste or type below. Each account name must be on its own line.<br>e.g.<br>misterhay<br>mpython<br>unladen.swallow<p>"));  
  var textArea = app.createTextArea().setName("textArea").setSize("20%", "60%").setStyleAttribute("background", "white").setStyleAttribute("color", "black").setFocus(true);  
  var serverHandler = app.createServerHandler("deleteAccounts").addCallbackElement(textArea);  
  var clientHandler = app.createClientHandler().forEventSource().setEnabled(false).setText("deleting accounts...");  
  app.add(textArea);  
  var button = app.createButton("Delete Accounts");  
  button.addClickHandler(serverHandler);  
  button.addClickHandler(clientHandler);  
  app.add(button);  
  app.add(app.createLabel("no accounts deleted").setId("finishedLabel").setVisible(false));  
  return app;  
 }  
   
 function deleteAccounts(eventInfo) {  
  var app = UiApp.createApplication();  
  var deleteThese = eventInfo.parameter.textArea;  
  var stringArray = deleteThese.split(/\n/);  
  for (var loopNumber = 0; loopNumber < stringArray.length; loopNumber++) {  
   var deleteThisUser = stringArray[loopNumber];  
 // rename the accounts before we delete them to avoid the five day wait before account names can be reused  
   var renamedUser = deleteThisUser + '_old';  
   Logger.log(renamedUser);  
 // delete the account  
   UserManager.getUser(deleteThisUser).setUsername(renamedUser);  
   UserManager.getUser(renamedUser).deleteUser();  
   }  
 // tell the user how many accounts we deleted.  
  app.getElementById("finishedLabel").setText(loopNumber + " accounts deleted").setVisible(true);  
  return app;  
 }  

Friday, December 20, 2013

Displaying Calendar Events on Digital Signage Using a Raspberry Pi and Google Apps Script

In our office many of us are often out of the building, so we decided to hang a TV that would display our calendar events. The hardware consists of a 40" LED mounted on the wall, with a Raspberry Pi (with a Wi-Fi adapter) connected to the HDMI input.

To display the calendars, a Google Apps Script edits a Google Sites page, that is refreshed on the Raspberry Pi every 30 minutes. Google Apps Script is great at parsing Google Calendars, but unfortunately there is some incompatibility with our Exchange calendars, so I ended up using Yahoo!Pipes to parse the ICS files served by our Exchange server.

I'll write out some instructions for recreating what I've done, but your results may vary. Feel free to ask for help in the comments or on social media.

Start by creating yourself a Google Site that has no navigation elements or other clutter. Probably the easiest is to create one from this template I've shared.

Next, a Yahoo!Pipe to parse the ICS files. If you can subscribe to the calendars in Google Calendar then you don't need this because you can use the Calendar Service in Google Apps Script. I'll leave it to you to figure out how to do that, though. If you want to use Yahoo!Pipes to parse ICS files, check out the pipe I created.

Then a Google Apps Script to add events to the Google Site you created. If you're not familiar with Google Sites, there are many tutorials and code examples. I'll just paste my script code in here and hope you can make sense of it.

//Remember to set up a trigger set up to run every 30 minutes, or at whatever frequency you prefer
function runThis() {
  var page = SitesApp.getPageByUrl("https://sites.google.com/whatever-your-site-is-should-be-here");
  var dateToday = new Date();
  //format the date to print at the top of the webpage
  var dayToday = Utilities.formatDate(dateToday, Session.getTimeZone(), "EEEE, MMMM dd");
  //put the date at the top of the web page
  var pageContent = "<div style='font-size:larger'>Today is " + dayToday + "</div><br>";
  //add the calendar stuff by calling the appropriate functions and appending to the variable
  var pageContent = pageContent + parseCalendar("Your Name","#00FF00","http://your-link-to-an-online-ics-file.ics");
  var pageContent = pageContent + parseCalendar("Another Name","#FF0000","http://a-link-to-another-online-ics-file.ics");
  page.setHtmlContent(pageContent);
}

function parseCalendar(name,color,iCalUrl) {
  //declare and empty pageContent variable that we will fill with calendar entries
  var pageContent = "";
  //format the iCal URL for submission to Yahoo!Pipes
   var replaceColon = iCalUrl.replace(":","%3A");
   var replaceSlash = replaceColon.replace(/\//g,"%2F");
   var translatediCalUrl = replaceSlash.replace(/@/g,"%40");
   //replace spaces with + signs
   var translatedName = name.replace(" ","+");
   //concatenate the strings to make a URL
   var rssUrl = "http://pipes.yahoo.com/pipes/pipe.run?CalendarURL=" + translatediCalUrl + "&Name=" + translatedName + "&_id=9e11d02f251ade5c10a6f5501bfe181f&_render=rss"; 
  //fetch the RSS feed from that URL
  var rssContent = UrlFetchApp.fetch(rssUrl).getContentText();
  //parse the RSS feed that we just fetched
  var items = XmlService.parse(rssContent).getRootElement().getChild("channel").getChildren("item");
  //loop through the items we just parsed
  for (var i = 0; i < items.length; i++) {
    var item = items[i];
    var title = item.getChild("title").getText();
    // if there is a location, then get it from the "description" field
    if (item.getChild("description") != null) {
      var location = item.getChild("description").getText();
      var output = title + " at " + location;
      }
    // if there isn't a location, output just the title
    else {output = title};
    var pageContent = pageContent + "<div style='color:" + color + "'>" + output + "</div>\r";
    }
  return pageContent;
}
Finally, on the Raspberry Pi:
  1. Set up Debian Linux on the Pi:http://www.raspberrypi.org/downloads
  2. (optional): Force the Raspberry Pi to use HDMI output even if it doesn't detect a display there:
    1. in the terminal emulator type  sudo leafpad /boot/config.txt
    2. add the following lines to that file:
      1. hdmi_force_hotplug=1
      2. hdmi_drive=2
    3. remove (or comment out) any similar lines at the bottom of the file that may have been added by the NOOBS install process
    4. save and close the config.txt file
  3. Have the mouse cursor auto-hide using unclutter: in the terminal emulator type  sudo apt-get install unclutter
  4. Edit the autostart file: in the terminal emulator type  sudo leafpad /etc/xdg/lxsession/LXDE/autostart
  5. Disable screen sleeping and autostart the browser by adding the following lines to the file you just opened for editing (include the @ signs, but not the line numbers):
    1. @xset s off
    2. @set -dpms
    3. @xset s noblank
    4. @midori -e Fullscreen -i 1800 -a https://sites.google.com/whatever-your-site-is-should-be-here
    5. @unclutter -display :0.0 -idle 5
  6. Reboot the Raspberry Pi, and you're done.

Wednesday, April 9, 2014

Check if Google Apps Users Have Logged in (Google Apps Script)

If you're using Google Apps for Education (with the provisioning API enabled) and have a list of domain users that you want to check if they've logged in or not, here's a quick Spreadsheet script you can try. It queries to see if the user has agreed to the terms or not. Of course you'll need to run this from an account that has admin permissions on your domain.

function onOpen() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [{name : "Start Checking", functionName : "startLoop"}];
  spreadsheet.addMenu("Check Users", entries);
}

function startLoop() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var activeSheet = sheet.getActiveSheet();
  var maxRows = activeSheet.getMaxRows();
  var result = Browser.msgBox('This script will check ' + maxRows + ' rows worth of data from the currently selected cell.', Browser.Buttons.OK_CANCEL);
  if (result != 'cancel') {
    for (var i=0;i<maxRows;i++) {checkUser();}
  } else {Browser.msgBox('Okay, maybe some other time');}
}

function checkUser() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var range = SpreadsheetApp.getActiveRange();
  var newRange =  range.offset(0, 1);
  var username = range.getValue();
  var user = UserManager.getUser(username);
  var agreedToTerms = user.getAgreedToTerms();
  newRange.setValue(agreedToTerms);
  var newSelection = range.offset(1, 0);
  newSelection.activate();
}

I'm assuming that you're somewhat familiar with Google Apps Script and using it with Spreadsheets. Let me know in the comments if you need clarification.

Wednesday, October 1, 2008

Google Apps Education Edition

I've talked before about Google Apps Education Edition with respect to student email addresses, but I wanted to revisit the other things that are included with this. Hopefully without sounding too much like a commercial.

Create, Edit, and Share Documents
Google Docs is like an online Office Suite. It includes a word processor, as well as spreadsheet and presentation programs. I've used it for student assignments (both that I assign and that they submit) and for sharing lab data amoung the students. Not quite as many features as Microsoft Office, but available from any computer with an Internet connection.

Calendar
The interface of Google calendar is, imho, better than any other calendar software I've used. It also allows for private, public, and shared calendars. I've used it for class test schedule reminders (embedded in my website) as well as for staff supervision scheduling. You can even integrate your calendar with out district's mandated school site. And it syncronizes with my iPod Touch.

Sites
Quick and easy way to create feature-rich websites for your domain, of which my website is an example. Teams, clubs, and even individual students can create "sites" if it is enabled.

All of these features, and a few that I haven't mentioned, can be enabled or disabled as you see fit. Google Apps Education Edition is not without its shortcomings, as I've mentioned, but I do have to say that I'm a big fan.

Tuesday, June 10, 2008

student email addresses

There are a few options for providing student email addresses. At my school we're using Google Apps Education Edition, and we like it. If you're looking for filtered email and don't mind somewhat more intrusive advertising, Gaggle.net is an option. Another option, though, is to use an existing FirstClass system and add students as users to it; this isn't as easy, and may not be free, but it is an option.

We have gmail (Google email) accounts for all 1250 or so of our students, as well as gmail accounts for the staff. Students can use their to forward assignments home, collaborate with other students, and get in touch with their teachers outside of class. I have also had students use them to hand in assignments (either as attachements or as Google documents), as email reminders or class communications (I have a group email list for each of my classes), and I have a shared calendar of upcoming assessments.

We've made up a list of the pros and cons of using Google Apps Education Edition.
Cons:
  • No uptime guarantee
  • Who owns your data?
  • No control over spam filter, password policies, logs, blacklists, etc (some of this is available through the API)
  • No directory lookup for >200 users
  • Advertising (although targeted text ads only)

Pros:

  • Free (but there are paid options)
  • Easy to setup and administrate
  • Bulk account upload/update
  • Stable
  • Good Spam Filtering
  • Other Apps (calendar, docs, etc.)
  • POP and IMAP
  • Lots of space (>6 GB per user)
  • API (provisioning, usage reports, SSO, etc.)

I recommend GAEE, and in fact there are quite a number of Universities implementing it as well. And hopefully we won't have to worry about Google going out of business.

Tuesday, March 18, 2014

Google Apps Script: Auto-Query FortiGuard Category List

In case someone is curious, here's a little Google Apps Script I put together for querying FortiGuard's Web Filtering Service site category list from a spreadsheet. It takes a URL from the selected cell in a Google Spreadsheet, and FortiGuard's category for that URL in the cell to the right of it.

function onOpen() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var menuEntries = [ {name: "pasteCategory", functionName: "pasteCategory"},
                      {name: "Say Hello", functionName: "sayHello"} ];
  sheet.addMenu("FortiGuard", menuEntries);
}

function pasteCategory() { //you can also set this to loop for the number of rows
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var range = SpreadsheetApp.getActiveRange();
  var newRange = range.offset(0, 1); //the cell to the right
  var site = range.getValue();//from the currently selected cell
  var category = getCategory(site);
  newRange.setValue(category) //paste in the category
  var newSelection = range.offset(1, 0);
  newSelection.activate();
}

function sayHello() {
  Browser.msgBox("Hello");
}

function getCategory(site) {
  var urlToFetch = "http://www.fortiguard.com/ip_rep/index.php?data="+site
  var html = UrlFetchApp.fetch(urlToFetch).getContentText();
  var startTag = 'Category: ';
  var endTag = '</h3>';
  var startIndex = html.indexOf(startTag) + 10; // add 10 to the index to get rid of 'Category: '
  var endIndex = html.indexOf(endTag);
  var category = html.slice(startIndex,endIndex);
  return(category);
}

Saturday, October 31, 2009

Wednesday, January 21, 2009

making a password protected website with Google sites

If you find that you need to have information available on the Internet to a limited number of people, perhaps your students, you can create a website using Google Sites. Google Sites can be used with a regular Google (Gmail) account, or with a Google Apps account (as I've discussed before.

When creating your site, you can specify if you want it viewable by the whole world, anyone from your domain, or specific users. You can also invite users to be collaborators, meaning that they can edit the pages on the site.

One thing to be careful of, however, is that it seems the option "Anyone at may this site." is not the default option. If you don't want your students to edit your site, you'll want to change that.

Wednesday, February 18, 2015

what I'm up to these days

A while back I had been blogging daily about what I do, but had found that I seemed to then gravitate towards tasks that I could accomplish easily and then write about at the end of the day.

Instead, I'm going to occasionally write about some things I'm working on. This will include work-related things as well as tasks and projects related to the Masters in Education that I'm hoping to have completed by April 2016.

One of the bigger work-related projects I'm working on these days is open data. We are working on getting some of our data on Strathcona County's Open Data Portal, as well as taking data that we already release and posting it in a more accessible format. We are also interested in getting teachers and students utilizing open data. As I write this, International Open Data Day is coming up soon.

On a somewhat-related note, we're also looking at Open Badges to highlight professional learning among staff in EIPS.

In terms of ongoing work in EIPS, I wrote up a list the other day of things we are often talking to staff about these days.
And a few things on my to do list at work:
  • publish to do list
  • plan Scratch Day
  • Moodle migration
  • automate creation of Google Apps users from PowerSchool
  • build a Minecraft server image with a web-based (or VNC) control panel
  • help plan summer school technology camps
  • explore web-based project management ideas
And a little Python script I wrote today to translate addresses into latitude and longitude coordinates:

Hopefully next time I'll write about some course-related things that are in progress.

Thursday, October 9, 2014

Python and Google Apps Provisioning with the Admin SDK Directory API

After wading through documentation, blog posts, and StackOverflow answers I've finally figured out a way to authenticate using OAuth 2.0. Since we didn't want to have to interactively grant "user consent" for each of our domains, this is acting as a "web server" for computer-computer interactions.

I assume that you have Python 2.7 installed (three shalt thou not use), but I'd recommend installing Anaconda to make your life easier for all of this. You'll also need to install the Google APIs Client Library for Python.

EDIT: I was finally able to get it to work with the default SignedJwtAssertionCredentials.
 as well as PyCryptoSignedJWT. To install PyCryptoSignedJWT, download and unzip, then from the command line (in the directory you unziped to) type python setup.py install in order to install.

The next step is to set up your project. Here's the documentation from here to "Set up your API":
  • Enable the API access from the Admin console in order to make requests to the Directory API. To enable the API, log in to your admin account and select Security. If you do not see Security listed, select More controls and then Security from the options shown in the gray box. Select API reference, and then select the checkbox to Enable API access. Save your changes.
  • Set up a new project in the Google APIs Console and activate Admin SDK service for this project. See the Google APIs Console Help in the upper right corner of the Console page for more information about creating your API project.




Still in the Developers Console, you'll need to create credentials for your project. Click on Credentials (under APIs) and click the button Create new Client ID and then select Service account.


Download the key file, and make a note of the private key password (which is always "notasecret"). Then click the Okay, got it button.

You'll need to make a note of the Service Account EMAIL ADDRESS that is displayed (a long string of characters ending in @developer.gserviceaccount.com) and the CLIENT ID (the same string ending with .apps.googleusercontent.com).

The next step requires you to authorize your API client to access your admin console. Assuming your're still logged in to your Super Admin account, go to Manage API client access (or go to Security, Advanced Settings, Authentication, Manage third party OAuth Client access). For the Client Name, paste in the CLIENT ID that you noted previously. In the One or More API Scopes, put in a comma-separated list of the scopes that you'll be using. For our example I'd suggest https://www.googleapis.com/auth/admin.directory.user, https://www.googleapis.com/auth/admin.directory.orgunit (you can always change this later). Then click the Authorize button.



The file you downloaded previously will be something like APIProject.p12 but we'll need to convert it to a PEM file. On a Mac or Linux machine this can be done from the command line ( openssl pkcs12 -passin pass:notasecret -in APIProject.p12 -nocerts -out APIProject.pem ), but on Windows other software is required (try Win32OpenSSL that can be downloaded from here). As a last resort for those who don't worry about security, you can convert it using this site.

So you now have a p12 key file, a Service Account Email Address, and of course your Super Admin account. You're set to start writing some code. I like the Spyder development environment that is installed with Anaconda, but feel free to just use Notepad (or Notepad++) if you're so inclined.

Here's the minimum Python code that works for me, fill in the appropriate values for yourself.


superAdmin = 'you@example.com'
serviceAccount = 'somethingorother@developer.gserviceaccount.com'
pemFile = 'APIProject.p12'
scope = 'https://www.googleapis.com/auth/admin.directory.user'

import httplib2
from apiclient.discovery import build
from oauth2client.client import SignedJwtAssertionCredentials

keyFile = file(p12File, 'rb')
key = keyFile.read()
keyFile.close()
credentials = SignedJwtAssertionCredentials(serviceAccount,
  key,
  scope,
  prn=superAdmin)

http = httplib2.Http()
httplib2.debuglevel = False #change this to True if you want to see the output
http = credentials.authorize(http=http)
directoryService = build(serviceName='admin', version='directory_v1', http=http)

# You are now authenticated, so you can say something like this:
user = directoryService.users().get(userKey = 'me@example.com')
print user.execute()



Hopefully that's enough to get you started. The documentation about what you can do with the Admin Directory API is here. just remember that some of them will require you to declare other scopes.

Friday, October 21, 2016

Google Classroom Assignment Completion Leaderboard

I've been using Google Classroom to post a lot of assignments that students can work on at their own pace; some of them are optional assignments, but most are required. We also have incentives set up for milestones such as 500 assignments completed by the class.

Rather than having to go through each assignment and see how many have been completed, and how many each student has completed, I've written a script that logs that information to a Google Spreadsheet. In case you'd like to do the same, here's the code and some basic instructions on how to set it up for yourself.
  1. Create a Google spreadsheet with a list of student email addresses in column A starting at row 2.
  2. Rename the sheet Achievements (or change line 17 of the code below).
  3. Under the Tools menu choose Script editor and paste in the code below.
  4. Follow the directions at https://developers.google.com/classroom/quickstart/apps-script to authorize your script.
  5. Run (play) the function listCourses to find the courseId for the course that you want to run this on
  6. Set up a trigger to run the function countClassroomAssignments() every morning or every week.

Monday, March 14, 2011

ideas of things to build

I have a number of projects on the back burner, or in most cases still in the cupboard, so I wanted to write some of them down here. You know, in case anyone is interested in helping or can point me to where these have already been constructed. Some are software, some are hardware, most are related to education.

  1. web app for bulk deleting users from Google Apps for Education (using Google App Engine)
  2. application allowing users to automatically add anyone who uses a particular hash tag to a Twitter list, similar to blastfollow (using Oauth, and perhaps Google App Engine or Chrome Web Store)
  3. something similar to Blippy for automatic sharing of which library books you have signed out
  4. an Android tablet app similar to Proloquo2Go for augmentative and alternative communication
  5. interfacing Vernier probes and sensors with a LaunchPad or Teensy
  6. locking shelf for securing (and syncing) multiple iPods in a classroom (using just a 2x4, a door hinge, and a lock plate)
  7. iPad cart or shelf similar to the Bretford Mobility Cart
  8. locking carrying case for six netbooks (for WISEST)
  9. real time control of a Mitsubishi Movemaster RM-101 robot arm using a keyboard or joystick (in BASIC)

I'm no Ben Heck, so I'd appreciate any help or direction with any of these.

Wednesday, May 15, 2013

form data averages Google Apps Script

When a Google Form is submitted, it adds a row to your spreadsheet. This changes your formulas, which is a problem if you are trying to do live calculations on submitted data, so you need a script to copy in the correct formulas after each form submission.

Here's an example of how I did that. The script is set to trigger whenever a form is submitted.

function insertAverage() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
  var formulas = [
   ["=AVERAGE(C3:C100)", "=AVERAGE(D3:D100)", "=AVERAGE(E3:E100)"]
   ];
  var destination = sheet.getRange("C2:E2");
  destination.setFormulas(formulas);
};

Friday, May 27, 2016

Technology Ideas to Enhance Classrooms and Makerspaces

not that a classroom can't also be a makerspace, in fact some argue that every classroom should be

Here are are a few cool things you can try with students of almost any age. Some off these are expensive, some are free. Try things and share your experiences.


Hour of Code

A basic introduction to coding and computational thinking concepts.
A good starting point before moving on to other projects.

Scratch Programming

A graphical (drag and drop) programming environment for creating games, animations, interactive stories, and presentations.
  • Can be used by any students that can read (probably best in grade 3 and up).
  • Works great on Chromebooks or any other machines.
  • There is also ScratchJr on tablets for younger students.
e.g. Math with Scratch Demo” by MisterHay
Math with Scratch Demonstration on Scratch_2016-05-09_10-48-34.jpg

Makey Makey

A small circuit board for interfacing real-world things with a computer/Chromebook.
  • Use wires to connect anything conductive, the computer sees it as a keyboard and mouse.
  • Works great with Scratch
Original (3699 × 2775)

mBot Robot

mBot is an easy-to-use and inexpensive ($100 or so) programmable robot.
Features:
  • Wireless connection to the computer
  • Two motors
  • Two RGB LEDs that can be programmed to display almost any color
  • Speaker (for playing tones/notes)
  • Infrared transmitter and receiver for communicating with other mBots, TVs, etc.
  • Ultrasonic distance sensor
  • Line follower sensor (can tell whether it is on a dark line or not)
It can be programmed with mBlock, which is based on Scratch, or via Arduino code.
e.g. line follower by JohannHöchtl


LEGO Mindstorms

Build with LEGO, program with a graphical environment.













e.g. NXT-G programming by Steve Jurvetson
On a related note, check out LEGO Digital Designer (for Windows or Mac) and Build with Chrome (for Chrome).

Raspberry Pi computer

A small, inexpensive (less than $50) single-board desktop computer.
  • Just requires a monitor, keyboard, mouse, and cables.
  • KanoOS is kid-friendly and has a number of great coding activities built in.
  • Many interesting projects have been built with them.


Virtual Circuits

123d.circuits.io allows students to create virtual circuits. Works on Chromebooks or other computers.

Google Cardboard Virtual Reality Headset

Very inexpensive, about $5 each.
Requires a relatively recent Android phone or iPhone (4S or newer).
Experience VR games and simulations
Watch 3D and/or 360° videos.
Students may even be able to record VR photos and videos using mobile apps.

Stop Motion Animation

On a Chromebook or any computer with a webcam: Chrome Stop Motion Animator app
iPhone, iPod, iPad: LEGO Movie Maker app, Imotion How too use Imotion
Many Android stop motion apps available as well.

Video and Audio Production

e.g. video projects, podcasts, radio dramas
Chromebooks:
Mobile Devices:

Quadcopter Drones

EIPS owns (and insures) two Phantom 3 video drones for schools can borrow.
Students can also fly smaller indoor drones such as a Syma X2.



Have fun.