Skip to content
This repository was archived by the owner on Jan 6, 2022. It is now read-only.

Commit 13441ef

Browse files
author
Gunjan Sharma
committed
A new python sample app. It uses Provisioning API along with Sites and Profiles API
1 parent 6194837 commit 13441ef

1 file changed

Lines changed: 367 additions & 0 deletions

File tree

samples/apps/org_unit_sites.py

Lines changed: 367 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,367 @@
1+
#!/usr/bin/python
2+
#
3+
# Copyright (C) 2007, 2009 Google Inc.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
__author__ = 'Gunjan Sharma <gunjansharma@google.com>'
18+
19+
import getopt
20+
import getpass
21+
import sys
22+
import time
23+
import atom
24+
import atom.data
25+
import gdata.apps.multidomain.client
26+
import gdata.apps.organization.service
27+
import gdata.apps.service
28+
import gdata.client
29+
import gdata.contacts.client
30+
import gdata.contacts.data
31+
import gdata.contacts.service
32+
import gdata.sites.client
33+
import gdata.sites.data
34+
35+
#The title for the site
36+
ORG_SITE_TITLE = 'Organization Hierarchy'
37+
#Title for the users site
38+
USER_SITE_TITLE = 'Users'
39+
#The template URI for a site
40+
URI = 'https://sites.google.com/a/%s/%s/'
41+
#Description for the sites
42+
DESCRIPTION = 'Under Construction'
43+
#Theme for the sites
44+
THEME = 'slate'
45+
#Header for the new webpages
46+
HTML_HEADER = ('<html:div xmlns:html="http://www.w3.org/1999/xhtml">'
47+
'<html:table cellspacing="0" class='
48+
'"sites-layout-name-one-column sites-layout-hbox"><html:tbody>'
49+
'html:tr><html:td class="sites-layout-tile '
50+
'sites-tile-name-content-1">')
51+
#Footer for the new webpages
52+
HTML_FOOTER = '</html:td></html:tr></html:tbody></html:table></html:div>'
53+
#The template string for each user's html page
54+
TEMPLATE_USER_HTML = ('<h2>Name:</h2><p>%s</p><h2>Gender:</h2><p> %s</p>'
55+
'<h2>Address:</h2><p>%s</p><h2>Email:</h2><p>%s</p>')
56+
57+
58+
class OrgUnitAddressBook(object):
59+
"""Creates organization unit sites from the domain."""
60+
61+
def __init__(self, email, password, domain):
62+
"""Constructor for the OrgUnitSites object.
63+
64+
Takes an email, password and domain to create a site map corresponding
65+
to the organization units in the domain.
66+
67+
Args:
68+
email: [string] The email address of the admin.
69+
password: [string] The password corresponding to the admin account.
70+
domain: [string] The domain for which sites are to be made.
71+
72+
Returns:
73+
A OrgUnitSites object used to run the site making.
74+
"""
75+
source = 'Making sites corresponding to org units'
76+
self.domain = domain
77+
# Create sites object
78+
self.sites_client = gdata.sites.client.SitesClient(source=source,
79+
domain=domain)
80+
self.sites_client.ClientLogin(email, password, self.sites_client.source);
81+
#Get the sites feed
82+
self.all_site_feed = self.sites_client.GetSiteFeed()
83+
84+
# Create google contacts object
85+
self.profiles_client = gdata.contacts.client.ContactsClient(domain=domain)
86+
self.profiles_client.client_login(email, password, 'cp', service='cp')
87+
88+
# Create an Organization Unit Client
89+
self.org_unit_client = gdata.apps.organization.service.OrganizationService(
90+
email=email, domain=domain, password=password)
91+
self.org_unit_client.ProgrammaticLogin()
92+
customer_id_set = self.org_unit_client.RetrieveCustomerId()
93+
self.customer_id = customer_id_set['customerId']
94+
95+
def _GetSiteName(self, site_title):
96+
"""Returns the corresponding site_name. This is needed since the site name
97+
isn't the same as the title.
98+
99+
Args:
100+
site_title: [string] The title for a site.
101+
102+
Returns:
103+
A string which is the corresponding site_name.
104+
"""
105+
site_name = site_title.replace(' ', '-')
106+
site_name = site_name.lower()
107+
return site_name
108+
109+
def _GetSiteURI(self, site_title):
110+
"""Returns the corresponding uri to the site.
111+
Needed to get the link to a particular user page.
112+
113+
Args:
114+
site_title: [string] The title for a site.
115+
116+
Returns:
117+
A string which is the corresponding site's URI.
118+
"""
119+
uri = URI % (self.domain, self._GetSiteName(site_title))
120+
return uri
121+
122+
def _CreateSite(self, site_title, description=DESCRIPTION, theme=THEME):
123+
"""Creates a site with the site_title, if it not already exists.
124+
125+
Args:
126+
site_title: [string] The title for a site.
127+
description: [string] The description for the site.
128+
theme: [string] The theme that should be set for the site.
129+
130+
Returns:
131+
A Content feed object for the created site.
132+
"""
133+
site_entry = None
134+
site_found = False
135+
site_name = self._GetSiteName(site_title)
136+
for site in self.all_site_feed.entry:
137+
if site.site_name.text == site_name:
138+
site_found = True
139+
site_entry = site
140+
break
141+
if site_found == False:
142+
try:
143+
site_entry = self.sites_client.CreateSite(site_title,
144+
description=description, theme=theme)
145+
except gdata.client.RequestError, error:
146+
print error
147+
self.sites_client.site = site_name
148+
return site_entry
149+
150+
def _DeleteAllPages(self):
151+
'''Deletes all the pages in a site except home'''
152+
feed_uri = self.sites_client.make_content_feed_uri()
153+
while feed_uri:
154+
feed = self.sites_client.GetContentFeed()
155+
for entry in feed.entry:
156+
if entry.page_name.text != 'home':
157+
self.sites_client.Delete(entry)
158+
feed_uri = feed.FindNextLink()
159+
160+
def _GetUsersProfileFeed(self):
161+
"""Retrieves all the user's profile.
162+
163+
Returns:
164+
A Dictionary of email address to ContentEntry objects
165+
"""
166+
profiles = []
167+
feed_uri = self.profiles_client.GetFeedUri('profiles')
168+
while feed_uri:
169+
feed = self.profiles_client.GetProfilesFeed(uri=feed_uri)
170+
profiles.extend(feed.entry)
171+
feed_uri = feed.FindNextLink()
172+
173+
profiles_dict = {}
174+
for profile in profiles:
175+
for email in profile.email:
176+
if email.primary and email.primary == 'true':
177+
profiles_dict[email.address] = profile
178+
break
179+
180+
return profiles_dict
181+
182+
def _CreateUserPageHTML(self, profile):
183+
"""Creates HTML for a user profile.
184+
185+
Args:
186+
profile: [gdata.contacts.data.ProfileEntry] It is the profile of the user
187+
whose HTML has to be created.
188+
189+
Returns:
190+
A String which is the HTML code.
191+
"""
192+
address_string = ''
193+
email_string = ''
194+
for address in profile.structured_postal_address:
195+
address_string = '%s<li>%s</li><br />' % (address_string, address)
196+
for email in profile.email:
197+
if email.primary and email.primary == 'true':
198+
email_string = '%s<li>%s</li><br />' % (email_string, email.address)
199+
200+
new_html = TEMPLATE_USER_HTML % (profile.name.full_name.text,
201+
str(profile.gender), address_string, email_string)
202+
203+
return HTML_HEADER + new_html + HTML_FOOTER
204+
205+
def _GetUserPageName(self, user_email):
206+
"""Creates a page name for a particular user depending on the
207+
email address.
208+
209+
Args:
210+
user_email: [string] The email address of the user.
211+
212+
Returns:
213+
A String which defines the user page name.
214+
"""
215+
user_page_name = user_email.replace('@', '-')
216+
user_page_name = user_page_name.replace('.', '_')
217+
user_page_name = user_page_name.lower()
218+
return user_page_name
219+
220+
def _CreateUserPages(self):
221+
"""Makes all the user pages"""
222+
223+
entry = self._CreateSite(USER_SITE_TITLE)
224+
225+
#Delete all the pages
226+
self._DeleteAllPages()
227+
228+
users_profile = self._GetUsersProfileFeed()
229+
users = self.org_unit_client.RetrieveAllOrgUsers(self.customer_id)
230+
for user in users:
231+
user_email = user['orgUserEmail']
232+
user_profile = users_profile[user_email]
233+
new_html = self._CreateUserPageHTML(user_profile)
234+
user_page_name = self._GetUserPageName(user_email)
235+
236+
self.sites_client.CreatePage('webpage', user_profile.name.full_name.text,
237+
html=new_html, page_name=user_page_name)
238+
239+
def _GetOrgUnitPageHTML(self, path):
240+
"""Creates HTML for a Org Unit Page.
241+
242+
Args:
243+
profile: [string] Path of the Org Unit.
244+
245+
Returns:
246+
A String which is the HTML code.
247+
"""
248+
249+
domain_users = self.org_unit_client.RetrieveOrgUnitUsers(self.customer_id,
250+
path)
251+
new_html = '<p>'
252+
for user in domain_users:
253+
user_email = user['orgUserEmail']
254+
user_page_name = self._GetUserPageName(user_email)
255+
site_uri = self._GetSiteURI(USER_SITE_TITLE)
256+
new_html = '%s<li><a href="%s">%s</a></li><br />' % (new_html,
257+
site_uri + user_page_name, user_email)
258+
new_html = new_html + '</p>'
259+
return HTML_HEADER + new_html + HTML_FOOTER
260+
261+
def _SetOrgSiteHomePage(self):
262+
"""Sets up the home page for Org Unit Site"""
263+
new_html = self._GetOrgUnitPageHTML('/')
264+
home_path = self._GetUnitPath()
265+
home_feed = self.sites_client.GetContentFeed(uri=home_path)
266+
home_feed.entry[0].title.text = self.domain
267+
home_feed.entry[0].content.html = new_html
268+
self.sites_client.Update(home_feed.entry[0])
269+
270+
def _GetUnitPath(self, path=None):
271+
"""Returns path to the parent unit
272+
273+
Args:
274+
parent_path: [string] Path of the Parent Org Unit.
275+
276+
Returns:
277+
A String which is the path to the parent.
278+
"""
279+
path_uri = '%s?path=/%s'
280+
if path:
281+
path = path.replace('+', '-')
282+
path = path.lower()
283+
path = 'home/' + path
284+
else:
285+
path = 'home'
286+
287+
uri = path_uri % (self.sites_client.MakeContentFeedUri(), path)
288+
return uri
289+
290+
def _CreateOrgUnitPages(self):
291+
"""Creates all the org unit pages"""
292+
293+
entry = self._CreateSite(ORG_SITE_TITLE)
294+
#Delete all the pages
295+
self._DeleteAllPages()
296+
297+
self._SetOrgSiteHomePage()
298+
299+
orgUnits = self.org_unit_client.RetrieveAllOrgUnits(self.customer_id)
300+
for unit in orgUnits:
301+
parent_uri = self._GetUnitPath(unit['parentOrgUnitPath'])
302+
parent_feed = self.sites_client.GetContentFeed(uri=parent_uri)
303+
304+
new_html = self._GetOrgUnitPageHTML(unit['orgUnitPath'])
305+
self.sites_client.CreatePage('webpage', unit['name'], html=new_html,
306+
parent=parent_feed.entry[0])
307+
308+
def Run(self):
309+
"""Controls the entire flow of the sites making process"""
310+
311+
print 'Starting the process. This may take few minutes.'
312+
print 'Creating user pages...'
313+
self._CreateUserPages()
314+
print 'User pages created'
315+
print 'Creating Organization Unit Pages'
316+
self._CreateOrgUnitPages()
317+
print 'Your website is ready, visit it at: %s' % (self._GetSiteURI(
318+
ORG_SITE_TITLE))
319+
320+
321+
def main():
322+
"""Runs the site making module using an instance of OrgUnitAddressBook"""
323+
# Parse command line options
324+
try:
325+
opts, args = getopt.getopt(sys.argv[1:], '', ['email=', 'pw=', 'domain='])
326+
except getopt.error, msg:
327+
print ('python org_unit_sites.py --email [emailaddress] --pw [password]'
328+
' --domain [domain]')
329+
sys.exit(2)
330+
331+
email = ''
332+
password = ''
333+
domain = ''
334+
# Parse options
335+
for option, arg in opts:
336+
if option == '--email':
337+
email = arg
338+
elif option == '--pw':
339+
password = arg
340+
elif option == '--domain':
341+
domain = arg
342+
343+
while not email:
344+
email = raw_input('Please enter admin email address (admin@example.com): ')
345+
while not password:
346+
sys.stdout.write('Admin Password: ')
347+
password = getpass.getpass()
348+
if not password:
349+
print 'Password cannot be blank.'
350+
while not domain:
351+
username, domain = email.split('@', 1)
352+
choice = raw_input('You have not given us the domain name. ' +
353+
'Is it %s? (y/n)' % (domain))
354+
if choice == 'n':
355+
domain = raw_input('Please enter domain name (domain.com): ')
356+
357+
try:
358+
org_unit_address_book = OrgUnitAddressBook(email, password, domain)
359+
except gdata.service.BadAuthentication:
360+
print 'Invalid user credentials given.'
361+
return
362+
363+
org_unit_address_book.Run()
364+
365+
366+
if __name__ == '__main__':
367+
main()

0 commit comments

Comments
 (0)