Use 'From Template' instead of 'Duplicate' to create new prof pages
[sitecorepy.git] / sitecore / prof / import.py
1 #!/usr/bin/env python
2 # Copyright (C) 2010 W. Trevor King <wking@drexel.edu>
3 #
4 # This file is part of SiteCorePy.
5 #
6 # SiteCorePy is free software; you can redistribute it and/or modify it
7 # under the terms of the GNU General Public License as published by the
8 # Free Software Foundation, either version 2 of the License, or (at your
9 # option) any later version.
10 #
11 # SiteCorePy is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 # General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with SiteCorePy.  If not, see <http://www.gnu.org/licenses/>.
18
19 """Move Professors from YAML -> Sitecore.
20
21 Professors will be created in:
22   Content -> Home -> physics -> contact -> facultyDirectory
23 """
24
25 import re
26 import time
27
28 from selenium.common.exceptions import NoSuchElementException
29 import yaml
30
31 from .. import SiteCoreConnection
32 from . import Name, Graduation, Contact, Bio, Professor
33
34
35 class ProfessorAdder (object):
36     """See doc/faculty.txt for Drexel's field/format policy.
37     """
38     def __init__(self, sitecore_connection):
39         self.s = sitecore_connection
40         self.regexps = {
41             'Degrees':re.compile('Degrees:.*', re.DOTALL),
42             'College':re.compile('College:.*', re.DOTALL),
43             'Program':re.compile('Program:.*', re.DOTALL),
44             'Office':re.compile('Office:.*', re.DOTALL),
45             'Specialization':re.compile('.*Specialization:.*', re.DOTALL),
46             'Research Interests':re.compile('.*Research Interests:.*',
47                                             re.DOTALL),
48             'Personal Site':re.compile('.*Personal Site:.*', re.DOTALL),
49             'Title':re.compile('.*Title:.*', re.DOTALL),
50             'First Name':re.compile('.*First Name:.*', re.DOTALL),
51             'Last Name':re.compile('.*Last Name:.*', re.DOTALL),
52             'Bio':re.compile('.*Bio:.*', re.DOTALL),
53             'Headshot':re.compile('.*Headshot:.*', re.DOTALL),
54             'Email':re.compile('.*Email:.*', re.DOTALL),
55             'Phone':re.compile('.*Phone:.*', re.DOTALL),
56             'Fax':re.compile('.*Fax:.*', re.DOTALL),
57             'Page Title':re.compile('.*Page Title -.*', re.DOTALL),
58             'Menu Title':re.compile('.*Menu Title -.*', re.DOTALL),
59             'Breadcrumb Title':re.compile('.*Breadcrumb Title -.*', re.DOTALL),
60             'See Also Title':re.compile('.*See Also title -.*', re.DOTALL),
61             }
62
63     def setup(self):
64         #self.s.expand_nav_section('sitecore')
65         #self.s.expand_nav_section('Content')
66         self.s.expand_nav_section('Home')
67         for i in range(5): # 'physics' takes a while to load
68             try:
69                 self.s.expand_nav_section('physics')
70             except NoSuchElementException, e:
71                 time.sleep(self.s.wait_time)
72         self.s.expand_nav_section('contact')
73         self.s.expand_nav_section('facultyDirectory')
74
75     def __call__(self, prof):
76         name = '%s %s' % (prof.name.first_middle, prof.name.last)
77         self.create_prof_page(name)
78         self.lock_section(name)
79         settings = [
80             ('Degrees', prof.degrees()),
81             ('College', prof.colleges()),
82             ('Program', prof.program()),
83             ('Office', prof.contact.office),
84             ('Specialization', prof.bio.specialization),
85             ('Research Interests', ''),
86             ('Personal Site', prof.sites()),
87             ('Title', prof.title),
88             ('First Name', prof.name.first_middle),
89             ('Last Name', prof.name.last),
90             ('Bio', prof.profile()),
91             ('Headshot', ('/Images/physics/headshots/%s'
92                            % name.lower().replace('.','').replace(' ','_'))),
93             ('Email', prof.contact.email),
94             ('Phone', prof.contact.phone),
95             ('Fax', prof.lab_contact()),
96             ('Page Title', name),
97             ('Menu Title', name),
98             ('Breadcrumb Title', name),
99             ('See Also Title', name),
100             ]
101         for field_name,value in settings:
102             if value == None:
103                 value = ''
104             granddad,field = self.s.find_field(self.regexps[field_name],
105                                                field_name)
106             try:
107                 editor_link = granddad.find_element_by_link_text('Edit Html')
108                 self.set_editor_field(editor_link, value)
109             except NoSuchElementException: # basic text field
110                 field.clear()
111                 field.send_keys(value)
112         #granddad,field = self.s.find_field('Headshot:')
113         #granddad.find_element_by_link_text('Properties')
114         # TODO, set width/height
115         self.s.publish_section('Added/updated Prof. %s' % prof.name.last)
116
117     def create_prof_page(self, name):
118         try:
119             self.s.open_nav_section(name)
120             return
121         except NoSuchElementException:
122             pass
123         old_windows = self.s.w.get_window_handles()
124         #self.s.w.find_element_by_link_text('Duplicate').click()
125         # WebDriver doesn't support JavaScript prompts:
126         #   http://code.google.com/p/selenium/wiki/FrequentlyAskedQuestions#Q:_Does_support_Javascript_alerts_and_prompts?
127         self.s.open_nav_section('facultyDirectory')
128         self.s.w.find_element_by_link_text('Developer').click()
129         time.sleep(self.s.wait_time)
130         self.s.w.find_element_by_link_text('From Template').click()
131         time.sleep(self.s.wait_time)
132         windows = self.s.w.get_window_handles()
133         current_window = self.s.w.get_current_window_handle()
134         popup = [w for w in windows if w not in old_windows][0]
135         if current_window != popup:
136             self.s.logger.info('handling copy popup %s (from %s, old %s)'
137                                % (popup, windows, current_window))
138             self.s.w.switch_to_window(popup)
139         template = self.s.w.find_element_by_id('TemplateName')
140         template.clear()
141         template.send_keys('/Drexel/FacultyProfile')
142         faculty = self.s.w.find_element_by_id('ItemName')
143         faculty.clear()
144         faculty.send_keys(name)
145         self.s.w.find_element_by_id('OK').click()
146         time.sleep(self.s.wait_time*5)
147         current_window = self.s.w.get_current_window_handle()
148         self.s.logger.info('handled copy popup %s, back to %s'
149                            % (popup, current_window))
150         self.s.open_nav_section(name)
151
152     def lock_section(self, name):
153         try:
154             self.s.lock_section()
155         except NoSuchElementException, e:
156             self.s.logger.info("can't lock %s (already locked?), skipping" % name)
157
158     def set_editor_field(self, editor_link, value):
159         pass  # TODO, save first.
160
161
162 def main(argv):
163     import optparse
164     usage = """%prog [options] PROF_FILE
165
166 Where PROF_FILE is a YAML file containing professor data.
167
168 Example setup before running:
169   Xvfb :99 > /dev/null 2>&1 &
170   export DISPLAY=:99
171   java -jar selenium-server-1.0.2-SNAPSHOT-standalone.jar > /dev/null 2>&1 &
172   ./sc.py prof-import profs.yaml
173 """
174     p = optparse.OptionParser(usage)
175     p.add_option('-u', '--url', metavar='URL', dest='url',
176                  help='set the website URL (%default)',
177                  default='https://webedit.drexel.edu/sitecore/login')
178     p.add_option('-v', '--verbose', dest='verbose', action='count',
179                  help='increment verbosity (%default)',
180                  default=0)
181
182     options,args = p.parse_args(argv[1:])
183     prof_file = args[0]
184     profs = yaml.load(open(prof_file, 'r'))
185
186     s = SiteCoreConnection(options.url, options.verbose)
187     s.start()
188     try:
189         s.login()
190         add = ProfessorAdder(s)
191         add.setup()
192         for prof in profs:
193             add(prof)
194     finally:
195         s.stop()