# HG changeset patch # User Santosh G. Vattam # Date 1249902493 -19800 # Node ID 21942fac2b4b226b680b672d32494f7a681dd8ed # Parent 2840389ee7f93092c136f9cd78555a30959e8543# Parent b39994cca7614154cbf4bd1e200928cd14fbe960 Merge vattam and default branches. diff -r 2840389ee7f9 -r 21942fac2b4b app/projrev/models.py --- a/app/projrev/models.py Thu Aug 06 18:49:06 2009 +0530 +++ b/app/projrev/models.py Mon Aug 10 16:38:13 2009 +0530 @@ -12,50 +12,697 @@ from django.contrib.auth.models import User +def sort_dict(d): + """Function to sort dictionary elements. + """ + + items = [(v, k) for k, v in d.items()] + items.sort() + return [(k, v) for v, k in items] + + class Project(models.Model): """Model class for NME funded projects. """ - LINE_ITEM_CHOICES = [('ME', 'Mechanical'), - ('CE', 'Chemical'), - ('EE', 'Electrical'), - ('AE', 'Aero Space'), - ('CS', 'Computer Science'), - ('IT', 'Information Technology'), - ] + LINE_ITEM_CHOICES = { + "NP": "NPTEL phase II / III", + "PG": "PG Classes", + "UG": "UG Classes", + "VC": "Video content digitization, conversion, chunking and dubbing CEC / IGNOU / NCERT / SIET / OTHERS", + "PE": "Provision of e-books and e-journals free to the learners", + "SQ": "Standardisation of quality assurance of contents & certification / automation of certification", + "DS": "Developing suitable pedagogical methods for various classes, intellectual calibers and research in e-learning", + "DL": "Development of language converter and translation tool kit", + "DR": "Development and realization of Virtual Reality Laboratories and supporting facilities for e-learning", + "DC": "Development of Certification & Testing Modules for Virtual Technological Universities & creation of VTU, multi media research and international programmes", + "ED": "Experimentation and Development of ultra low cost access devices for wider coverage of learners & their field trials", + "TT": "Talk to a teacher to provide a substitute for coaching for the economically poor students", + "DH": "Development of software controlled hardware programming for robotics other crucial areas", + "AD": "Adaptation & deployment of open source simulation packages equivalent to MATLAB, ORCAD etc.", + "DU": "Development of unified ERP system for Educational Institutions", + "PT": "Publicity & training of motivators & trainers to ensure full utilization of the systems by institutions & students. Teacher Empowerment 'B'", + "CC": "Conversion of available content in various regional languages", + "DV": "Development of Vocational Educational modules and use of haptic devices for education & training", + } + + STATE_CHOICES = { + "AN": "Andaman & Nicobar", + "DN": "Dadra and Nagar Haveli", + "DL": "Delhi", + "WB": "West Bengal", + "HR": "Haryana", + "HP": "Himachal Pradesh", + "UP": "Uttar Pradesh", + "JH": "Jharkhand", + "BR": "Bihar", + "JK": "Jammu & Kashmir", + "TN": "Tamil Nadu", + "LD": "Lakshadweep", + "NL": "Nagaland", + "PY": "Pondicherry", + "TR": "Tripura", + "PB": "Punjab", + "DD": "Daman & Diu", + "RJ": "Rajasthan", + "CH": "Chandigarh", + "CG": "Chattisgarh", + "AP": "Andhra Pradesh", + "AS": "Assam", + "AR": "Arunachal Pradesh", + "GA": "Goa", + "GJ": "Gujarat", + "KA": "Karnataka", + "UA": "Uttarakhand", + "ML": "Meghalaya", + "MN": "Manipur", + "MH": "Maharashtra", + "KL": "Kerala", + "SK": "Sikkim", + "MP": "Madhya Pradesh", + "OR": "Orissa", + "MZ": "Mizoram" + } - STATE_CHOICES = [('MH', 'Maharashtra'), - ('KA', 'Karnataka'), - ('KL', 'Kerala'), - ('TN', 'Tamil Nadu'), - ('AP', 'Andra Pradesh'), - ] - - DISTRICT_CHOICES = [('AD', 'Adilabad'), - ('RT', 'Ratnagiri'), - ('MU', 'Mumbai suburban'), - ('PU', 'Pune'), - ('PL', 'Palakkad'), - ('BN', 'Bangalore Urban district'), - ('CK', 'Chikmagalur District'), - ] + DISTRICT_CHOICES = { + "JHES": "Purba Singhbhum", + "TNRA": "Ramanathapuram", + "PBAM": "Amritsar", + "ORMY": "Mayurbhanj", + "UPMG": "Maharajganj", + "ORML": "Malkangiri", + "MZAI": "Aizawl", + "NLKO": "Kohima", + "PBFR": "Faridkot", + "ARPA": "Papum Pare", + "SKES": "East Sikkim", + "UAPI": "Pithoragharh", + "MHNS": "Nashik", + "PBFI": "Firozpur", + "KAKD": "Kodagu", + "APRA": "Rangareddi", + "BRSO": "Sheohar", + "UPSV": "Shravasti", + "KAKL": "Kolar District", + "PYPO": "Puducherry", + "UPSU": "Sultanpur", + "UPSR": "Sant Ravidas Nagar", + "MHRT": "Ratnagiri", + "UPSN": "Siddharthnagar", + "PBHO": "Hoshiarpur", + "UPSJ": "Shahjahanpur", + "KAKP": "Koppal District", + "UPSI": "Sitapur", + "BRSP": "Sheikhpura", + "BRSR": "Saran", + "BRSU": "Supaul", + "BRST": "Sitamarhi", + "BRSW": "Siwan", + "UPSA": "Saharanpur", + "KADH": "Dharwad District", + "JHLO": "Lohardaga", + "ASSO": "Sonitpur", + "KADK": "Dakshina Kannada", + "ASSI": "Sibsagar", + "KADA": "Davanagere District", + "ORJP": "Jajapur (Jajpur)", + "ORJS": "Jagatsinghpur", + "UPMP": "Mainpuri", + "MHBU": "Buldhana", + "TNKR": "Karur", + "WBME": "Midnapore", + "UPUN": "Unnao", + "TNKC": "Kanchipuram", + "SKSS": "South Sikkim", + "MPUM": "Umaria", + "JKJA": "Jammu", + "MPUJ": "Ujjain", + "CGMA": "Mahasamund", + "GJPA": "Patan", + "UACL": "Chamoli", + "PYMA": "Mahe", + "GJPO": "Porbandar", + "GJPM": "Panchmahal", + "RJHA": "Hanumangarh", + "WBDD": "Dakshin Dinajpur", + "WBDA": "Darjeeling", + "HPUN": "Una", + "PBFT": "Fatehgarh Sahib", + "MHLA": "Latur", + "GJVD": "Vadodara", + "UPLK": "Lakhimpur Kheri", + "JHBO": "Bokaro", + "HRHI": "Hissar", + "WBJA": "Jalpaiguri", + "UPDE": "Deoria", + "MPRE": "Rewa", + "MPRG": "Rajgarh", + "MPRL": "Ratlam", + "ASLA": "Lakhimpur", + "MPRS": "Raisen", + "HPMA": "Mandi", + "PBMU": "Mukatsar", + "BRPA": "Patna", + "BRRO": "Rohtas", + "PBMA": "Mansa", + "BRPU": "Purnia", + "PBMO": "Moga", + "RJSR": "Sirohi", + "MHAH": "Ahmednagar", + "MHAK": "Akola", + "MHAM": "Amrawati", + "HRSN": "Sonepat", + "MHAU": "Aurangabad", + "ARTI": "Tirap", + "PBBA": "Bathinda", + "RJSK": "Sikar", + "KAUD": "Udupi District", + "RJSM": "Sawai Madhopur", + "RJAJ": "Ajmer", + "APVZ": "Vizianagaram", + "RJAL": "Alwar", + "MHWR": "Wardha", + "MHWS": "Washim", + "APVS": "Vishakhapatnam", + "KAHV": "Haveri District", + "KAHS": "Hassan District", + "MPGW": "Gwalior", + "MPGU": "Guna", + "JHPK": "Pakur", + "JHPL": "Palamu", + "UPEW": "Etawah", + "UPKU": "Kushinagar", + "UPKS": "Kaushambi", + "BRSH": "Saharsa", + "UPKD": "Kanpur Dehat", + "PBPA": "Patiala", + "UPKN": "Kanpur Nagar", + "BRSM": "Samastipur", + "UPVA": "Varanasi", + "UPKJ": "Kannauj", + "APCH": "Chittoor", + "HRRE": "Rewari", + "NLZU": "Zunheboto", + "BRBU": "Buxar", + "HRRO": "Rohtak", + "TNCH": "Chennai", + "BRBJ": "Bhojpur", + "UATG": "Tehri Garhwal", + "BRBG": "Bhagalpur", + "BRBE": "Begusarai", + "BRBA": "Banka", + "MHHI": "Hingoli", + "UPJP": "Jyotiba Phule Nagar", + "GJBR": "Bharuch", + "GJBV": "Bhavnagar", + "GJBK": "Banaskantha", + "TRST": "South Tripura", + "GANG": "North Goa", + "ORPU": "Puri", + "KACK": "Chikballapur District", + "UPSO": "Sonbhadra", + "HRMW": "Mewat", + "RJTO": "Tonk", + "NLDI": "Dimapur", + "HRMA": "Mahendragarh", + "UPSK": "Sant Kabir Nagar", + "MZCH": "Champhai", + "BRLA": "Lakhisarai", + "UPJH": "Jhansi", + "ARAJ": "Anjaw", + "UAUS": "Udham Singh Nagar", + "UPRB": "Rae Bareli", + "UAUT": "Uttarkashi", + "ASTI": "Tinsukia", + "KLKL": "Kollam", + "KLKN": "Kannur", + "KLKS": "Kasaragod", + "KLKT": "Kottayam", + "KLKZ": "Kozhikode", + "MHBI": "Beed", + "MPHA": "Harda", + "MHBH": "Bhandara", + "MHST": "Satara", + "MPHO": "Hoshangabad", + "MHSN": "Sangli", + "MHSO": "Solapur", + "ASBA": "Barpeta", + "KASH": "Shimoga District", + "MHSI": "Sindhudurg", + "ASBO": "Bongaigaon", + "MZLU": "Lunglei", + "MPCT": "Chhatarpur", + "BRKI": "Kishanganj", + "BRKH": "Khagaria", + "HPSO": "Solan", + "KLTV": "Thiruvananthapuram", + "BRKM": "Kaimur", + "HPSH": "Shimla", + "KLTS": "Thrissur", + "MNCC": "Churachandpur", + "ORBH": "Bhadrak", + "MZLA": "Lawngtlai", + "BRKT": "Katihar", + "ORJH": "Jharsuguda", + "MPCN": "Chhindwara", + "APCU": "Kadapa", + "ORBD": "Boudh (Bauda)", + "PYKA": "Karaikal", + "UPGZ": "Ghaziabad", + "UPGR": "Gorkakhpur", + "UPGP": "Ghazipur", + "GASG": "South Goa", + "JHCH": "Chatra", + "MHOS": "Osmanabad", + "UPGN": "Gonda", + "GJAH": "Ahmedabad", + "WBNA": "Nadia", + "GJAM": "Amreli District", + "GJAN": "Anand", + "JKBR": "Baramula", + "APGU": "Guntur", + "ASMA": "Marigaon", + "JKBD": "Badgam", + "WBUD": "Uttar Dinajpur", + "TNSI": "Sivagangai", + "TNSA": "Salem", + "MHDH": "Dhule", + "PBNS": "Nawan Shehar", + "PBGU": "Gurdaspur", + "ARWK": "West Kameng", + "RJPA": "Pali", + "UPAG": "Agra", + "WBBI": "Birbhum", + "RJPG": "Pratapgarh", + "JKPO": "Poonch", + "KLPL": "Palakkad", + "APPR": "Prakasam", + "KLPT": "Pathanamthitta", + "TNAY": "Ariyalur", + "JKPU": "Pulwama", + "RJBW": "Bhilwara", + "RJBN": "Banswara", + "AREL": "Lohit", + "RJBM": "Barmer", + "AREK": "East Kameng", + "RJBI": "Bikaner", + "ORCU": "Cuttack", + "RJBU": "Bundi", + "RJBR": "Baran", + "KLWA": "Wayanad", + "RJBP": "Bharatpur", + "MHYA": "Yavatmal", + "ORAN": "Angul", + "UPAU": "Auraiya", + "WBMA": "Malda", + "MPTI": "Tikamgarh", + "GJSN": "Surendranagar", + "APNE": "Nellore", + "GJSK": "Sabarkantha", + "APNI": "Nizamabad", + "DLSW": "South West Delhi", + "BRGA": "Gaya", + "DLSD": "South Delhi", + "GJST": "Surat", + "UPBD": "Badaun", + "ORSO": "Subarnapur (Sonepur)", + "JHGI": "Giridih", + "JHGO": "Godda", + "WBHR": "Howrah", + "TNTJ": "Thanjavur", + "TNTK": "Thoothukudi", + "JHGA": "Garhwa", + "TNTI": "Tirunelveli", + "TNTL": "Thiruvallur", + "ORSA": "Sambalpur", + "KLER": "Ernakulam", + "TNKK": "Kanyakumari", + "TNTP": "Tiruppur", + "TNTV": "Tiruvannamalai", + "WBMU": "Murshidabad", + "MHKO": "Kolhapur", + "ORSU": "Sundargarh (Sundergarh)", + "UPBG": "Bagpat", + "JHGU": "Gumla", + "SKNS": "North Sikkim", + "RJUD": "Udaipur", + "TRDH": "Dhalai", + "MLEG": "East Garo Hills", + "UPCD": "Chandauli", + "HRJH": "Jhajjar", + "HRJI": "Jind", + "MLSG": "South Garo Hills", + "DLCD": "Central Delhi", + "UPCT": "Chitrakoot", + "MNUK": "Ukhrul", + "DLED": "East Delhi", + "PBJA": "Jalandhar", + "CGRN": "Rajnandgaon", + "PYYA": "Yanam", + "KABG": "Belgaum District", + "KABD": "Bidar District", + "KABJ": "Bijapur District", + "KABK": "Bagalkot District", + "CGRG": "Raigarh", + "KABN": "Bangalore Urban district", + "KABL": "Bellary District", + "KABR": "Bangalore Rural District", + "UPPR": "Pratapgarh", + "CGRP": "Raipur", + "TNTC": "Tiruchirappalli", + "UPME": "Meerut", + "MLEK": "East Khasi Hills", + "DLWD": "West Delhi", + "UPMB": "Mau", + "UPMO": "Moradabad", + "UPMH": "Mahoba", + "KATU": "Tumkur District", + "MPKA": "Katni", + "UPMT": "Mathura", + "UPMU": "Muzaffarnagar", + "TNMA": "Madurai", + "JKLE": "Leh", + "APMA": "Mahbubnagar", + "ASCA": "Cachar", + "APME": "Medak", + "MHRG": "Raigad", + "MPBP": "Bhopal", + "MPBR": "Barwani", + "MNBI": "Bishnupur", + "GJVL": "Valsad", + "NLPH": "Phek", + "RJNA": "Nagaur", + "BRDA": "Darbhanga", + "MPBE": "Betul", + "MPBD": "Bhind", + "PBLU": "Ludhiana", + "MPBL": "Balaghat", + "MZKO": "Kolasib", + "APNA": "Nalgonda", + "HPBI": "Bilaspur", + "UPJU": "Jaunpur District", + "GJDG": "The Dangs", + "GJDA": "Dahod", + "WBHG": "Hooghly", + "NLWO": "Wokha", + "MPPA": "Panna", + "UPJL": "Jalaun", + "ASJO": "Jorhat", + "WBKO": "Kolkata", + "HPKU": "Kulu", + "HRSI": "Sirsa", + "MLJH": "Jaintia Hills", + "HPKI": "Kinnaur", + "UADD": "Dehradun", + "UACP": "Champawat", + "HPKA": "Kangra", + "TNPU": "Pudukkottai", + "JHKO": "Koderma", + "UPRA": "Rampur", + "TNPE": "Perambalur", + "HRAM": "Ambala", + "MHGO": "Gondiya", + "KLAL": "Alappuzha", + "MHGA": "Gadchiroli", + "KAMA": "Mandya District", + "BRMP": "Madhepura", + "BRMZ": "Muzaffarpur", + "BRMG": "Munger", + "JKSR": "Samba", + "BRMB": "Madhubani", + "KAMY": "Mysore District", + "RJGA": "Ganganagar", + "BRGO": "Gopalganj", + "ORDH": "Dhenkanal", + "MPEN": "Khandwa (East Nimar)", + "JHRA": "Ranchi", + "JHRM": "Ramgarh District", + "BRVA": "Vaishali", + "HPLS": "Lahaul and Spiti", + "GJKA": "Kutch", + "UARP": "Rudraprayag", + "GJKH": "Kheda", + "MPSI": "Sidhi", + "MPWN": "Khargone (West Nimar)", + "PBRU": "Rupnagar", + "MNSE": "Senapati", + "APAN": "Anantapur", + "NLTU": "Tuensang", + "CGJA": "Jashpur", + "ASGG": "Golaghat", + "CGJC": "Janjgir-Champa", + "APAD": "Adilabad", + "RJJW": "Jhalawar", + "UPMI": "Mirzapur", + "RJJS": "Jaisalmer", + "RJJP": "Jaipur", + "ASGP": "Goalpara", + "RJJL": "Jalore", + "RJJJ": "Juhnjhunun", + "HPHA": "Hamirpur", + "MPSR": "Sehore", + "TNTH": "Theni", + "MLWG": "West Garo Hills", + "CGDH": "Dhamtari", + "MHND": "Nanded", + "MHNG": "Nagpur", + "MLWK": "West Khasi Hills", + "CGDA": "Dantewada", + "HRFT": "Fatehabad", + "CGDU": "Durg", + "HRFR": "Faridabad", + "TNTR": "Thiruvarur", + "UPFI": "Firozabad", + "JKAN": "Anantnag", + "UPFT": "Fatehpur", + "ASNL": "Nalbari", + "APKA": "Karimnagar", + "HRPP": "Panipat", + "UPFR": "Farrukhabad", + "ASNG": "Nagaon", + "ASNC": "North Cachar Hills", + "UPFZ": "Faizabad", + "MNTH": "Thoubal", + "WBPN": "North 24 Parganas", + "TRWT": "West Tripura", + "MNTA": "Tamenglong", + "PBKA": "Kapurthala", + "RJDA": "Dausa", + "WBPS": "South 24 Parganas", + "UPPI": "Pilibhit", + "KLMA": "Malappuram", + "ARCH": "Changlang", + "WBPU": "Purulia", + "MHCH": "Chandrapur", + "KACJ": "Chamarajnagar District", + "ORKN": "Kandhamal", + "ORKO": "Koraput", + "ORKL": "Kalahandi", + "ORKJ": "Kendujhar (Keonjhar)", + "ORKH": "Khordha", + "NLMK": "Mokokchung", + "ORKP": "Kendrapara", + "NLMN": "Mon", + "KACT": "Chitradurga District", + "CGSU": "Surguja", + "MPNE": "Neemuch", + "TNNM": "Namakkal", + "MPNA": "Narsinghpur", + "TNNI": "The Nilgiris", + "TNNG": "Nagapattinam", + "APHY": "Hyderabad", + "UANA": "Nainital", + "APSR": "Srikakulam", + "RJCR": "Churu", + "RJCT": "Chittorgarh", + "MZMA": "Mamit", + "MHMC": "Mumbai City", + "UPET": "Etah", + "GJGA": "Gandhinagar", + "MHMU": "Mumbai suburban", + "WBKB": "Cooch Behar", + "HPCH": "Chamba", + "MPSG": "Sagar", + "HRPK": "Panchkula", + "ASKR": "Karimganj", + "MPSO": "Seoni", + "GJNV": "Navsari", + "MPSJ": "Shajapur", + "MPSH": "Shahdol", + "GJNR": "Narmada", + "MPSV": "Shivpuri", + "MPST": "Satna", + "ASKA": "Karbi Anglong", + "MPSP": "Sheopur", + "APEG": "East Godavari", + "HRPW": "Palwal", + "JKDO": "Doda", + "ASKK": "Kokrajhar", + "JHDU": "Dumka", + "ORRA": "Rayagada", + "JHDE": "Deoghar", + "MHJG": "Jalgaon", + "HRBH": "Bhiwani", + "TNDH": "Dharmapuri", + "JHDH": "Dhanbad", + "MHJN": "Jalna", + "UPBI": "Bijnor", + "UPBH": "Bahraich", + "UPBL": "Ballia", + "UPBN": "Banda District", + "HRKR": "Karnal", + "UPBB": "Barabanki", + "MZSE": "Serchhip", + "HRKU": "Kurukshetra", + "HRKT": "Kaithal", + "MNCD": "Chandel", + "MZSA": "Saiha", + "UPBP": "Balrampur", + "UPBS": "Basti", + "UPBR": "Bareilly", + "UPBU": "Bulandshahr", + "MLRB": "Ri-Bhoi", + "JKRA": "Rajauri", + "ORBR": "Bargarh (Baragarh)", + "BRNW": "Nawada", + "MHTH": "Thane", + "HPSI": "Sirmaur", + "RJDU": "Dungapur", + "APWA": "Warangal", + "ORBW": "Baleswar (Balasore)", + "TNER": "Erode", + "BRNL": "Nalanda", + "MPDE": "Dewas", + "KAGU": "Gulbarga District", + "TRNT": "North Tripura", + "KLID": "Idukki", + "MPDI": "Dindori", + "MPDH": "Dhar", + "KAGA": "Gadag District", + "MPDT": "Datia", + "JHSA": "Sahibganj", + "ORGP": "Gajapati", + "UAPG": "Pauri Garhwal", + "ORBL": "Bolangir (Balangir)", + "MPJH": "Jhabua", + "UPLA": "Lalitpur", + "MPJA": "Jabalpur", + "JKKR": "Kargil", + "JKKT": "Kathua", + "JKKU": "Kupwara", + "WBBN": "Bankura", + "KAUK": "Uttara Kannada", + "ASDI": "Dibrugarh", + "UPLU": "Lucknow", + "WBBR": "Bardhaman", + "ASDM": "Dhemaji", + "ASDA": "Darrang", + "ASDB": "Dhubri", + "HRYN": "Yamuna Nagar", + "BREC": "Purba Champaran", + "UABA": "Bageshwar", + "TNCU": "Cuddalore", + "MPMS": "Mandsaur", + "MPML": "Mandla", + "GJRA": "Rajkot", + "MPMO": "Morena", + "TNCO": "Coimbatore", + "GJJU": "Junagadh", + "TNVE": "Vellore", + "TNVL": "Villupuram", + "UPHR": "Hardoi", + "ORDE": "Debagarh (Deogarh)", + "HRGU": "Gurgaon", + "RJJO": "Jodhpur", + "UPAH": "Allahabad", + "UPAL": "Aligarh", + "UPAN": "Ambedkar Nagar", + "CGBI": "Bilaspur", + "APWG": "West Godavari", + "UPAZ": "Azamgarh", + "CGBA": "Bastar", + "ORNY": "Nayagarh", + "BRWC": "Pashchim Champaran", + "ORNU": "Nuapada", + "MNWI": "Imphal West", + "UAAL": "Almora", + "JHHA": "Hazaribagh", + "ORNB": "Nabarangpur", + "ARUD": "Dibang Valley", + "ARUB": "Upper Subansiri", + "RJRA": "Rajsamand", + "APKR": "Krishna", + "MHPU": "Pune", + "APKU": "Kurnool", + "MPIN": "Indore", + "ASHA": "Hailakandi", + "UPGB": "Gautam Buddha Nagar", + "MHPA": "Parbhani", + "KARA": "Raichur District", + "SKWS": "West Sikkim", + "APKH": "Khammam", + "KARM": "Ramanagara District", + "DLNO": "North Delhi", + "BRJE": "Jehanabad", + "BRJA": "Jamui", + "JHWS": "Pashchim Singhbhum", + "DLND": "New Delhi", + "DLNE": "North East Delhi", + "DLNW": "North West Delhi", + "RJDH": "Dholpur", + "TNDI": "Dindigul", + "JKUD": "Udhampur", + "GJJA": "Jamnagar", + "UPHM": "Hamirpur", + "PBSA": "Sangrur", + "MPVI": "Vidisha", + "ORGN": "Ganjam", + "MHNB": "Nandurbar", + "UPHT": "Mahamaya Nagar", + "BRAR": "Araria", + "JKBP": "Bandipore", + "CGKB": "Korba", + "BRAU": "Aurangabad", + "CGKK": "Kanker", + "CGKJ": "Koriya", + "CGKW": "Kawardha", + "UAHA": "Haridwar", + "GJMA": "Mehsana", + "RJKO": "Kota", + "MNEI": "Imphal East", + "RJKA": "Karauli", + "ARLB": "Lower Subansiri", + "MPDM": "Damoh" + } # Field containing the Line Item to which the project belongs to. line_item = models.CharField(max_length=256, - choices=LINE_ITEM_CHOICES) + choices=tuple(LINE_ITEM_CHOICES)) + line_item.help_text = 'Select from one of the Line Items.' # Field containing the name of the institution working on the # project. institution = models.CharField(max_length=256) + institution.help_text = 'Give the full name of your institution.' # Field containing the state to which the institution belongs to. - state = models.CharField(max_length=256, - choices=STATE_CHOICES) + state = models.CharField( + max_length=256, + choices=sorted(STATE_CHOICES.items(), key=lambda (k,v): (v,k))) + state.help_text = 'Select the state in which this project is taken up.' # Field containing the district to which the institution belongs # to in the state of India. district = models.CharField(max_length=256, - choices=DISTRICT_CHOICES) + choices=sort_dict(DISTRICT_CHOICES)) + district.help_text = ('First select the state before selecting the district. ' + 'Select the district of the state where this project is taken up.') + + mobile_num = models.CharField(max_length=20) + mobile_num.help_text = 'Enter your mobile number.' + + fax_num = models.CharField(max_length=20, null=True, blank=True) + fax_num.help_text = 'Enter your fax number with the code.' # Field containing the autogenerated MICR code for the project. micr_code = models.CharField(max_length=15, unique=True) @@ -67,21 +714,22 @@ choices=[('new', 'New'), ('pilot', 'Pilot'), ('invalid', 'Invalid')]) + last_updated_on = models.DateTimeField(auto_now=True) + @classmethod def getLineItem(cls, code): """Get the State name from its code. """ - line_item_dict = dict(cls.LINE_ITEM_CHOICES) - return line_item_dict[code] + return cls.LINE_ITEM_CHOICES[code] @classmethod def getLineItemCode(cls, name): """Get the Line Item code from its name. """ - for ln_code, ln_name in cls.LINE_ITEM_CHOICES: - if ln_name == name: + for ln_code in cls.LINE_ITEM_CHOICES: + if cls.LINE_ITEM_CHOICES[ln_code] == name: return ln_code return None @@ -91,16 +739,15 @@ """Get the State code from its name. """ - state_dict = dict(cls.STATE_CHOICES) - return state_dict[code] + return cls.STATE_CHOICES[code] @classmethod def getStateCode(cls, name): """Get the State code from its name. """ - for st_code, st_name in cls.STATE_CHOICES: - if st_name == name: + for st_code in cls.STATE_CHOICES: + if cls.STATE_CHOICES[st_code] == name: return st_code return None @@ -110,16 +757,15 @@ """Get the District name from its code. """ - district_dict = dict(cls.DISTRICT_CHOICES) - return district_dict[code] + return cls.DISTRICT_CHOICES[code] @classmethod def getDistrictCode(cls, name): """Get the District code from its name. """ - for dt_code, dt_name in cls.DISTRICT_CHOICES: - if dt_name == name: + for dt_code in cls.DISTRICT_CHOICES: + if cls.DISTRICT_CHOICES[dt_code] == name: return dt_code return None @@ -133,6 +779,7 @@ #: Field containing the Line Item to which the project belongs to. document = models.FileField(upload_to='proposals/%Y/%m/%d') + document.help_text = 'Select the document path from your local file system.' #: Field containing the date on which the document was submitted submitted_on = models.DateTimeField(auto_now_add=True) @@ -196,38 +843,48 @@ #: Field containing the comment entered along with the review. comment = models.TextField() + comment.help_text = "Enter your review comment about this proposal." #: Field representing the reference to the person who #: did the review. reviewer = models.ForeignKey(User, null=True) #: Field containing the date and time of review of the proposal. - reviewed_on = models.DateTimeField(auto_now_add=True) + reviewed_on = models.DateTimeField(auto_now=True) #: Field containing the review value for this attribute. attribute1 = models.PositiveSmallIntegerField( choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]) + attribute1.verbose_name = '' attribute2 = models.PositiveSmallIntegerField( choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]) + attribute1.verbose_name = '' attribute3 = models.PositiveSmallIntegerField( choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]) + attribute1.verbose_name = '' attribute4 = models.PositiveSmallIntegerField( choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]) + attribute1.verbose_name = '' attribute5 = models.PositiveSmallIntegerField( choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]) + attribute1.verbose_name = '' attribute6 = models.PositiveSmallIntegerField( choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]) + attribute1.verbose_name = '' attribute7 = models.PositiveSmallIntegerField( choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]) + attribute1.verbose_name = '' attribute8 = models.PositiveSmallIntegerField( choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]) + attribute1.verbose_name = '' attribute9 = models.PositiveSmallIntegerField( choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]) + attribute1.verbose_name = '' \ No newline at end of file diff -r 2840389ee7f9 -r 21942fac2b4b app/projrev/views/base.py --- a/app/projrev/views/base.py Thu Aug 06 18:49:06 2009 +0530 +++ b/app/projrev/views/base.py Mon Aug 10 16:38:13 2009 +0530 @@ -9,6 +9,8 @@ from django.core.urlresolvers import reverse from django.http import HttpResponseRedirect +from django.shortcuts import render_to_response +from django.template import RequestContext def home(request): @@ -22,4 +24,5 @@ else: return HttpResponseRedirect(reverse('app.projrev.views.proposal.submit')) else: - return HttpResponseRedirect(reverse('app.projrev.views.login.login_validate')) + template = 'projrev/home.html' + return render_to_response(template, RequestContext(request, {})) diff -r 2840389ee7f9 -r 21942fac2b4b app/projrev/views/helpers/access.py --- a/app/projrev/views/helpers/access.py Thu Aug 06 18:49:06 2009 +0530 +++ b/app/projrev/views/helpers/access.py Mon Aug 10 16:38:13 2009 +0530 @@ -7,21 +7,61 @@ ] -def checkAccess(func, request): +from functools import wraps + +from django.shortcuts import render_to_response +from django.template import RequestContext + +# Dictionary containing access checks for views. +# Keys: View function name. +# Values: proposer or staff +rights = {} + +def register(access_type): + """Function to register access type for a View function + """ + + def wrapper(func): + """The decorator for registering access checks. + """ + + rights['%s.%s' % (func.__module__, func.__name__)] = access_type + return func + + return wrapper + +def checkAccess(func): """ To check the access of the user and then return the appropriate function -object + object. """ - user_kind = rights[func.__name__] - if user.is_authenticated(): - if user_kind == 'staff': - if user.is_staff: - return func(request) - else: - return - - if user_kind == 'proposer': - if not user.is_staff: - return func(request) - else: - return - \ No newline at end of file + + @wraps(func) + def wrapper(request, *args, **kwargs): + """The decorator for access check. + """ + + user_kind = rights['%s.%s' % (func.__module__, func.__name__)] + user = request.user + + template = 'projrev/error.html' + context = {} + + if user.is_authenticated(): + if user_kind == 'reviewer': + if user.is_staff: + return func(request, *args, **kwargs) + else: + context['not_staff'] = True + return render_to_response(template, RequestContext(request, context)) + + if user_kind == 'proposer': + if not user.is_staff: + return func(request, *args, **kwargs) + else: + context['not_proposer'] = True + return render_to_response(template, RequestContext(request, context)) + else: + context['not_authenticated'] = True + return render_to_response(template, RequestContext(request, context)) + + return wrapper \ No newline at end of file diff -r 2840389ee7f9 -r 21942fac2b4b app/projrev/views/helpers/forms.py --- a/app/projrev/views/helpers/forms.py Thu Aug 06 18:49:06 2009 +0530 +++ b/app/projrev/views/helpers/forms.py Mon Aug 10 16:38:13 2009 +0530 @@ -6,7 +6,9 @@ '"Madhusudan.C.S" ', ] + from django import forms +from django.contrib.auth.models import User from projrev.models import Project from projrev.models import Review @@ -15,7 +17,7 @@ """Creates a form for the project. """ - document = forms.FileField() + document = forms.FileField(required=False, help_text='Select the document path from your local file system.') class Meta: # We store most of the data in Project model. So even though the @@ -25,7 +27,9 @@ # fields in the Project that must not appear in the form, but have # be automatically generated. - fields = ('line_item', 'institution', 'state', 'district') + fields = ('line_item', 'institution', 'state', + 'district', 'mobile_num', 'fax_num') + class ReviewForm(forms.ModelForm): """Creates a form for review of proposal. @@ -34,9 +38,10 @@ project = forms.ModelChoiceField(queryset=Project.objects.all(), widget=forms.HiddenInput(), required=False) + reviewer = forms.ModelChoiceField(queryset=User.objects.all(), + widget=forms.HiddenInput(), + required=False) class Meta: # Create a form from Review data model. model = Review - - exclude = ('reviewer') diff -r 2840389ee7f9 -r 21942fac2b4b app/projrev/views/helpers/templatetags/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/projrev/views/helpers/templatetags/__init__.py Mon Aug 10 16:38:13 2009 +0530 @@ -0,0 +1,7 @@ +"""Module for all the template tags. +""" + + +__authors__ = [ + '"Madhusudan.C.S" ', +] diff -r 2840389ee7f9 -r 21942fac2b4b app/projrev/views/helpers/templatetags/review_helpers.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/projrev/views/helpers/templatetags/review_helpers.py Mon Aug 10 16:38:13 2009 +0530 @@ -0,0 +1,52 @@ +"""A Django template tag library containing forms helpers. +""" + +__authors__ = [ + '"Madhusudan.C.S" ', +] + + +from django import template + +register = template.Library() + + +@register.inclusion_tag('projrev/templatetags/_as_review.html') +def as_review(review): + """Returns the comment contexts for the template tag. + """ + + total_score = (review.attribute1 + review.attribute2 + review.attribute3 + + review.attribute4 + review.attribute5 + review.attribute6 + + review.attribute7 + review.attribute8 + review.attribute9) + + return {'review': review, 'total_score': total_score} + +@register.inclusion_tag('projrev/templatetags/_as_my_review.html') +def as_my_review(review): + """Returns the comment contexts for the template tag. + """ + + total_score = (review.attribute1 + review.attribute2 + review.attribute3 + + review.attribute4 + review.attribute5 + review.attribute6 + + review.attribute7 + review.attribute8 + review.attribute9) + + project = review.project + proposal = project.proposal_set.all().order_by('-submitted_on')[0] + + review_context = { + 'review': review, + 'total_score': total_score, + } + + if proposal: + proposal_path = str(proposal.document) + proposal_name = proposal_path.split('/')[-1] + review_context['proposal_path'] = proposal_path + review_context['proposal_name'] = proposal_name + review_context['institution'] = project.institution + review_context['state'] = project.state + review_context['district'] = project.district + review_context['line_item'] = project.line_item + + return review_context diff -r 2840389ee7f9 -r 21942fac2b4b app/projrev/views/login.py --- a/app/projrev/views/login.py Thu Aug 06 18:49:06 2009 +0530 +++ b/app/projrev/views/login.py Mon Aug 10 16:38:13 2009 +0530 @@ -9,8 +9,10 @@ from django.contrib.auth import authenticate from django.contrib.auth import login +from django.contrib.auth import logout from django.contrib.auth.forms import AuthenticationForm from django.contrib.auth.models import User +from django.core.urlresolvers import reverse from django.db import IntegrityError from django.http import HttpResponseRedirect from django.shortcuts import render_to_response @@ -21,6 +23,9 @@ """Validate the user and log him in. """ + template = 'projrev/auth/login.html' + context = {} + if request.POST: username = request.POST['username'] password = request.POST['password'] @@ -28,16 +33,16 @@ if user is not None: if user.is_active: login(request, user) - return HttpResponseRedirect('/proposal/submit/') + if user.is_staff: + return HttpResponseRedirect('/proposal/review/') + else: + return HttpResponseRedirect('/proposal/submit/') else: pass # Return a 'disabled account' error message else: # Return an 'invalid login' error message. - pass - else: - context = {} - template = 'projrev/auth/login.html' + context['error'] = True return render_to_response(template, context) @@ -53,6 +58,21 @@ try: user = User.objects.create_user(username, username, password) user.save() + subject = "[Sakshath] Registration at Saskshath portal" + message = """Hi, + We have received a request for registration of your email address, +"%s", to the http://sakshath.ac.in portal. + +Your login credentials are: + username: %s + password: %s + +-- +Regards, +Saksath admin""" % (username, username, password) + + user.email_user(subject=subject, message=message) + context = { 'created': True, 'username': username, @@ -76,15 +96,20 @@ """Resend the password if forgotten. """ + template = 'projrev/auth/forgot_password.html' if request.POST: - pass + context = { + 'password_sent': True, + } else: context = {} - template = 'projrev/auth/forgot_password.html' + return render_to_response(template, context) def logout_view(request): """Logout the user """ - \ No newline at end of file + + logout(request) + return HttpResponseRedirect(reverse('app.projrev.views.base.home')) diff -r 2840389ee7f9 -r 21942fac2b4b app/projrev/views/proposal.py --- a/app/projrev/views/proposal.py Thu Aug 06 18:49:06 2009 +0530 +++ b/app/projrev/views/proposal.py Mon Aug 10 16:38:13 2009 +0530 @@ -8,22 +8,25 @@ ] +import json import os import time from django.core.urlresolvers import reverse +from django.http import HttpResponse from django.http import HttpResponseRedirect -from django.shortcuts import render_to_response, get_object_or_404 +from django.shortcuts import render_to_response +from django.template import RequestContext from projrev.models import Project from projrev.models import Proposal +from projrev.models import Review from projrev.views.helpers import access from projrev.views.helpers import forms as projrev_forms -rights = {} -rights['getMicr'] = 'proposer' - +@access.register('proposer') +@access.checkAccess def getMicr(request): """View to get MICR Code from the user. """ @@ -46,7 +49,8 @@ context = { 'error': True, } - return render_to_response(template, context) + return render_to_response(template, + RequestContext(request, context)) else: if submit == 'Edit Proposal for MICR Code': return HttpResponseRedirect( @@ -60,8 +64,10 @@ template = 'projrev/proposal/get_micr.html' context = {} - return render_to_response(template, context) + return render_to_response(template, RequestContext(request, context)) +@access.register('proposer') +@access.checkAccess def submit(request, micr_code=None): """View for proposal submission. """ @@ -83,40 +89,65 @@ if prop_form.is_valid(): cleaned_data = prop_form.cleaned_data - # Generate MICR code - cleaned_data['micr_code'] = '%s%s%s%d' % ( - cleaned_data['state'], cleaned_data['district'], - cleaned_data['line_item'], - int(time.time() * 1000) % 1000000000) + if micr_code: + project = Project.objects.get(micr_code=micr_code) + project.line_item = Project.getLineItem(cleaned_data['line_item']) + project.institution = cleaned_data['institution'] + project.state = Project.getState(cleaned_data['state']) + project.district = Project.getDistrict(cleaned_data['district']) + else: + # Generate MICR code + cleaned_data['micr_code'] = '%s%s%d' % ( + cleaned_data['district'], cleaned_data['line_item'], + int(time.time() * 1000) % 1000000000) + + cleaned_data['line_item'] = Project.getLineItem(cleaned_data['line_item']) + cleaned_data['state'] = Project.getState(cleaned_data['state']) + cleaned_data['district'] = Project.getDistrict(cleaned_data['district']) + + prop_form.cleaned_data = cleaned_data - cleaned_data['line_item'] = Project.getLineItem(cleaned_data['line_item']) - cleaned_data['state'] = Project.getState(cleaned_data['state']) - cleaned_data['district'] = Project.getDistrict(cleaned_data['district']) + # If the form is valid create a new project or update the project + # if it already exists from the form. + project = prop_form.save() + + project.micr_code = cleaned_data['micr_code'] - prop_form.cleaned_data = cleaned_data + subject = "[Sakshath] MICR Code of the new proposal submitted" + message = """Hi, + We have received a new proposal for National Mission on education from your, +email address "%s", to the http://sakshath.ac.in portal. The MICR Code of the +submitted proposal is: + MICR Code: %s - # If the form is valid create a new project or update the project - # if it already exists from the form. - project = prop_form.save() +Please remember this code for all future references. + + +-- +Regards, +Saksath admin""" % (request.user.username, project.micr_code) + + request.user.email_user(subject=subject, message=message) project.status = 'new' - project.micr_code = cleaned_data['micr_code'] - micr_code = cleaned_data['micr_code'] + micr_code = project.micr_code project.save() - # Create a proposal for the project. - proposal = project.proposal_set.create( - document=prop_form.cleaned_data['document'], rev_num = 0) + if prop_form.cleaned_data['document']: + # Create a proposal for the project. + proposal = project.proposal_set.create( + document=prop_form.cleaned_data['document'], + submitted_by=request.user, rev_num = 0) - proposal.save() + proposal.save() return HttpResponseRedirect( reverse('app.projrev.views.proposal.submit', args=(micr_code,))) - return HttpResponseRedirect('') + return submitGet(request, micr_code, prop_form) -def submitGet(request, micr_code=None): +def submitGet(request, micr_code=None, prop_form=None): """Handles GET request for the submission of proposal form. """ @@ -132,15 +163,20 @@ 'state': Project.getStateCode(project.state), 'district': Project.getDistrictCode(project.district), } - prop_form = projrev_forms.ProposalForm( - initial=initial_vals, instance=project) + if not prop_form: + prop_form = projrev_forms.ProposalForm( + initial=initial_vals, instance=project) - proposal_path = str(project.proposal_set.all()[0].document) + proposal = project.proposal_set.all().order_by('-submitted_on')[0] - proposal_name = proposal_path.split('/')[-1] + if proposal: + proposal_path = str(proposal.document) - context['proposal_path'] = proposal_path - context['proposal_name'] = proposal_name + proposal_name = proposal_path.split('/')[-1] + + context['proposal_path'] = proposal_path + context['proposal_name'] = proposal_name + context['last_submitted'] = proposal.submitted_on if 'HTTP_REFERER' in request.META: referer = request.META['HTTP_REFERER'].split('/') @@ -153,15 +189,25 @@ context['created_now'] = True context['micr_code'] = project.micr_code + + reviews = project.review_set.all().order_by('-reviewed_on') + if reviews: + context['last_reviewed'] = reviews[0].reviewed_on + context['nr_reviews'] = len(reviews) + else: - prop_form = projrev_forms.ProposalForm() + if not prop_form: + + prop_form = projrev_forms.ProposalForm() context['form'] = prop_form template = 'projrev/proposal/submit.html' - return render_to_response(template, context) + return render_to_response(template, RequestContext(request, context)) +@access.register('proposer') +@access.checkAccess def withdraw(request, micr_code=None): """View Method for withdrawal of proposal. """ @@ -177,8 +223,10 @@ template = 'projrev/proposal/withdraw.html' - return render_to_response(template, context) + return render_to_response(template, RequestContext(request, context)) +@access.register('reviewer') +@access.checkAccess def review(request, micr_code=None): """View for reviewing the proposal. """ @@ -198,10 +246,13 @@ cleaned_data = rev_form.cleaned_data cleaned_data['project'] = Project.objects.get(micr_code=micr_code) + cleaned_data['reviewer'] = request.user # If the form is valid create a new project or update the project # if it already exists from the form. review = rev_form.save() + return HttpResponseRedirect( + reverse('app.projrev.views.proposal.rank', args=(micr_code,))) return reviewGet(request, micr_code, rev_form) @@ -209,70 +260,82 @@ """ """ + context = {} + if not micr_code: template = 'projrev/proposal/list.html' - context = { - 'projects': Project.objects.all(), - 'row_url': '/proposal/review/', - } + context['projects'] = Project.objects.all().exclude( + status__exact='invalid').order_by('-last_updated_on') + context['row_url'] = '/proposal/review/' - return render_to_response(template, context) + return render_to_response(template, RequestContext(request, context)) if not rev_form: rev_form = projrev_forms.ReviewForm() - proposal_path = str(Project.objects.get( - micr_code=micr_code).proposal_set.all()[0].document) + project = Project.objects.get(micr_code=micr_code) + context['form'] = rev_form + context['project'] = project - proposal_name = proposal_path.split('/')[-1] + proposal = project.proposal_set.all().order_by('-submitted_on')[0] + + if proposal: + proposal_path = str(proposal.document) - context = { - 'form': rev_form, - 'project': Project.objects.get(micr_code=micr_code), - 'proposal_path': proposal_path, - 'proposal_name': proposal_name, - } + proposal_name = proposal_path.split('/')[-1] + + context['proposal_path'] = proposal_path + context['proposal_name'] = proposal_name + context['last_submitted'] = proposal.submitted_on + + reviews = project.review_set.all().order_by('reviewed_on') + if reviews: + context['reviews'] = reviews + context['last_reviewed'] = reviews[len(reviews)-1].reviewed_on + context['nr_reviews'] = len(reviews) template = 'projrev/proposal/review.html' - return render_to_response(template, context) + return render_to_response(template, RequestContext(request, context)) +@access.register('reviewer') +@access.checkAccess def rank(request, micr_code=None): """ """ - if request.method == 'POST': - return rankPost(request, micr_code) - else: - return rankGet(request, micr_code) - -def rankPost(request, micr_code=None): - """ - """ - - return rankGet(request, micr_code) - -def rankGet(request, micr_code=None): - """ - """ + context = {} if not micr_code: template = 'projrev/proposal/list.html' - context = { - 'projects': Project.objects.all(), - 'row_url': '/proposal/rank/', - } + context['projects'] = Project.objects.all().exclude( + status__exact='invalid').order_by('-last_updated_on') + context['row_url'] = '/proposal/rank/' + + return render_to_response(template, RequestContext(request, context)) - return render_to_response(template, context) + project = Project.objects.get(micr_code=micr_code) + + proposal = project.proposal_set.all().order_by('-submitted_on')[0] + + if proposal: + proposal_path = str(proposal.document) - projects = Project.objects.get(micr_code=micr_code) + proposal_name = proposal_path.split('/')[-1] - proposal_path = str(projects.proposal_set.all()[0].document) + context['proposal_path'] = proposal_path + context['proposal_name'] = proposal_name + context['last_submitted'] = proposal.submitted_on - proposal_name = proposal_path.split('/')[-1] + # Get all the reviews and put them to context. + reviews = project.review_set.all().order_by('reviewed_on') + nr_reviews = len(reviews) + if reviews: + context['reviews'] = reviews + context['last_reviewed'] = reviews[len(reviews)-1].reviewed_on + context['nr_reviews'] = nr_reviews - reviews = projects.review_set.all() - + # Calculate the review scores review_score = [0] * 9 for review in reviews: review_score[0] += review.attribute1 @@ -287,14 +350,71 @@ total_score = sum(review_score) - context = { - 'project': projects, - 'proposal_path': proposal_path, - 'proposal_name': proposal_name, - 'review_score': review_score, - 'total_score': total_score, - } + # Get the Average for each attribute + review_avg = [0] * 9 + for i, rs in enumerate(review_score): + try: + review_avg[i] = "%.2f" % (float(rs) / nr_reviews) + except ZeroDivisionError: + review_avg[i] = 0 + + try: + total_avg = "%.2f" % (float(total_score) / nr_reviews) + except ZeroDivisionError: + total_avg = 0 + + context['project'] = project + context['review_score'] = review_score + context['total_score'] = total_score + context['review_avg'] = review_avg + context['total_avg'] = total_avg template = 'projrev/proposal/rank.html' - return render_to_response(template, context) + return render_to_response(template, RequestContext(request, context)) + +def getDistrictsForState(request): + """View function that sends the districts for the given state code via AJAXy. + """ + + get_params = request.GET + if get_params: + st_code = get_params['_value'] + dt_dict = Project.DISTRICT_CHOICES + + # Get the Districts corresponding to the given State code. + dt_names = {} + count = 1 + for dt_code in dt_dict: + if dt_code[:2] == st_code: + dt_names[dt_code] = dt_dict[dt_code] + count += 1 + + # Sort the List based on District Name. + dt_send = [{'': "---------" }] + dt_names_sorted = sorted(dt_names.items(), key=lambda (k,v): (v,k)) + for dt_code, dt_name in dt_names_sorted: + dt_send.append({dt_code: dt_name}) + + return HttpResponse(json.dumps(dt_send)) + + return HttpResponse(None) + +@access.register('reviewer') +@access.checkAccess +def listMyReviews(request): + """View function to list all reviews given by a user. + """ + context = {} + + # Get all the reviews and put them to context. + reviews = Review.objects.all().order_by('reviewed_on') + nr_reviews = len(reviews) + if reviews: + context['reviews'] = reviews + context['last_reviewed'] = reviews[len(reviews)-1].reviewed_on + context['nr_reviews'] = nr_reviews + + template = 'projrev/proposal/myreviews.html' + + return render_to_response(template, RequestContext(request, context)) diff -r 2840389ee7f9 -r 21942fac2b4b app/scripts/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/scripts/__init__.py Mon Aug 10 16:38:13 2009 +0530 @@ -0,0 +1,3 @@ +__authors__ = [ + '"Madhusudan.C.S" ', +] \ No newline at end of file diff -r 2840389ee7f9 -r 21942fac2b4b app/scripts/fetch_data.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/scripts/fetch_data.py Mon Aug 10 16:38:13 2009 +0530 @@ -0,0 +1,54 @@ +"""Module to fetch data. +""" + +__authors__ = [ + '"Madhusudan.C.S" ', +] + + +import json + + +def fetch_state_code(file_name): + """Fetch State Codes + """ + + fh = file(file_name) + states = {} + for line in fh: + name, code = line.split('\t') + name = name.strip() + code = code.strip() + states[code] = name + print json.dumps(states, indent=4) + +def fetch_district_code(file_name, write_file): + """Fetch District Codes + """ + + fh = file(file_name) + districts = {} + for line in fh: + if line == '\n' or line[:4] == 'See ' or line[:4] == 'Code': + continue + if line[:6] == '[edit]': + state = line[6:].strip().split()[-1].strip('()') + continue + district_line = line.split('\t') + code = '%s%s' % (state, district_line[0].strip()) + name = district_line[1].strip() + districts[code] = name + if len(code) > 4: + print code, name + fh.close() + district_data = json.dumps(districts, indent=6) + fh = file(write_file, "w") + fh.write(district_data) + fh.close() + +if __name__ == '__main__': + import sys + if sys.argv[1] == 'fetch_state_code': + fetch_state_code(sys.argv[2]) + if sys.argv[1] == 'fetch_district_code': + fetch_district_code(sys.argv[2], sys.argv[3]) \ No newline at end of file diff -r 2840389ee7f9 -r 21942fac2b4b app/settings.py --- a/app/settings.py Thu Aug 06 18:49:06 2009 +0530 +++ b/app/settings.py Mon Aug 10 16:38:13 2009 +0530 @@ -9,6 +9,8 @@ ('Madhusudan.C.S', 'madhusudancs@gmail.com'), ) +DEFAULT_FROM_EMAIL = 'admin@sakshath.ac.in' + MANAGERS = ADMINS DATABASE_ENGINE = 'mysql' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. @@ -92,4 +94,5 @@ 'django.contrib.sites', 'django.contrib.admin', 'app.projrev', + 'app.projrev.views.helpers', ) diff -r 2840389ee7f9 -r 21942fac2b4b app/site-content/css/colorbox.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/site-content/css/colorbox.css Mon Aug 10 16:38:13 2009 +0530 @@ -0,0 +1,35 @@ +/* + ColorBox Core Style + The following rules are the styles that are consistant between all ColorBox themes +*/ +#colorbox, #cboxOverlay, #cboxWrapper{position:absolute; top:0; left:0; z-index:9999; overflow:hidden;} +#cboxOverlay{position:fixed; width:100%; height:100%;} +#cboxMiddleLeft, #cboxBottomLeft{clear:left;} +#cboxContent{position:relative; overflow:visible;} +#cboxLoadedContent{overflow:auto;} +#cboxLoadedContent iframe{display:block; width:100%; height:100%; border:0;} +#cboxTitle{margin:0;} +#cboxLoadingOverlay, #cboxLoadingGraphic{position:absolute; top:0; left:0; width:100%;} +#cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{cursor:pointer;} + +/* + ColorBox example user style + These rules are ordered and tabbed in a way that represents the order/nesting of the generated HTML, + in hope that this will make the relationship easier to understand. Thanks, jack@colorpowered.com +*/ +#cboxOverlay{background:#000;} + +#colorbox{} + #cboxContent{background:#000; margin-top:20px;} + #cboxLoadedContent{background:#000; padding:5px;} + #cboxTitle{position:absolute; top:-20px; left:0; color:#ccc;} + #cboxCurrent{position:absolute; top:-20px; right:0px; color:#ccc;} + #cboxSlideshow{position:absolute; top:-20px; right:90px; color:#fff;} + #cboxPrevious{position:absolute; top:50%; left:5px; margin-top:-32px; background:url(/site-content/images/controls.png) top left no-repeat; width:28px; height:65px; text-indent:-9999px;} + #cboxPrevious.hover{background-position:bottom left;} + #cboxNext{position:absolute; top:50%; right:5px; margin-top:-32px; background:url(/site-content/images/controls.png) top right no-repeat; width:28px; height:65px; text-indent:-9999px;} + #cboxNext.hover{background-position:bottom right;} + #cboxLoadingOverlay{background:#000;} + #cboxLoadingGraphic{background:url(/site-content/images/loading.gif) center center no-repeat;} + #cboxClose{position:absolute; top:5px; right:5px; display:block; background:url(/site-content/images/controls.png) top center no-repeat; width:38px; height:19px; text-indent:-9999px;} + #cboxClose.hover{background-position:bottom center;} diff -r 2840389ee7f9 -r 21942fac2b4b app/site-content/css/jquery-purr.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/site-content/css/jquery-purr.css Mon Aug 10 16:38:13 2009 +0530 @@ -0,0 +1,54 @@ +/* jquery purr */ + +#purr-container { + position:fixed; + bottom:0; + right:0; +} + +.tooltip { + position: relative; + width: 300px; +} + +.tooltip .close { + position: absolute; + top: 12px; + right: 12px; + display: block; + width: 18px; + height: 17px; + text-indent: -9999px; + background: url('/site-content/images/purrClose.png') no-repeat 0 10px; +} + +.tooltip-body { + min-height: 50px; + padding: 22px 22px 0 22px; + background: url('/site-content/images/purrTop.png') no-repeat left top; + color: #f9f9f9; +} + +.tooltip-body img { + width: 50px; + margin: 0 10px 0 0; + float: left; +} + +.tooltip-body h3 { + margin: 0; + font-size: 2em; + text-align: left; +} + +.tooltip-body p { + margin: 5px 0 0 60px; + font-size: 1em; + text-align: left; + line-height: 1.4em; +} + +.tooltip-bottom { + height: 22px; + background: url('/site-content/images/purrBottom.png') no-repeat left top; +} \ No newline at end of file diff -r 2840389ee7f9 -r 21942fac2b4b app/site-content/css/jquery.rating.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/site-content/css/jquery.rating.css Mon Aug 10 16:38:13 2009 +0530 @@ -0,0 +1,69 @@ +/* jQuery.Rating Plugin CSS - http://www.fyneworks.com/jquery/star-rating/ */ +div.rating-cancel { + float:left; + width:17px; + height:15px; + margin-left: 3%; + text-indent:-999em; + cursor:pointer; + display:block; + background:transparent; + overflow:hidden; +} + +div.star-rating { + float:left; + width:17px; + height:15px; + text-indent:-999em; + cursor:pointer; + display:block; + background:transparent; + overflow:hidden; +} + +div.rating-cancel,div.rating-cancel a { + background:url(/site-content/images/delete.gif) no-repeat 0 -16px +} + +div.star-rating,div.star-rating a { + background:url(/site-content/images/star.gif) no-repeat 0 0px +} + +div.rating-cancel a,div.star-rating a { + display:block; + width:16px; + height:100%; + background-position:0 0px; + border:0 +} + +div.star-rating-on a { + background-position:0 -16px!important +} + +div.star-rating-hover a { + background-position:0 -32px +} + +/* Read Only CSS */ +div.star-rating-readonly a{ + cursor:default !important +} +/* Partial Star CSS */ +div.star-rating{ + background:transparent!important; + overflow:hidden!important +} +/* END jQuery.Rating Plugin CSS */ + +label { + float: left; + width: 40%; + position: relative; + top: -5px; + font-weight:bold; + margin:5px 0; + margin-right: 1em; + text-align: right; +} \ No newline at end of file diff -r 2840389ee7f9 -r 21942fac2b4b app/site-content/css/login.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/site-content/css/login.css Mon Aug 10 16:38:13 2009 +0530 @@ -0,0 +1,21 @@ +* { margin: 0; padding: 0; } +body { font-family: Georgia, serif; background: url(/site-content/images/login-page-bg.jpg) top center no-repeat #c4c4c4; color: #3a3a3a; } + +.clear { clear: both; } + +form { width: 406px; margin: 170px auto 0; } + +legend { display: none; } + +fieldset { border: 0; } + +label { width: 115px; text-align: right; float: left; margin: 0 10px 0 0; padding: 9px 0 0 0; font-size: 14px; } + +input { width: 220px; display: block; padding: 4px; margin: 0 0 10px 0; font-size: 14px; + color: #3a3a3a; font-family: Georgia, serif;} +input[type=checkbox]{ width: 20px; margin: 0; display: inline-block; } + +.button { background: url(/site-content/images/button-bg.png) repeat-x top center; border: 1px solid #999; + -moz-border-radius: 5px; padding: 5px; color: black; font-weight: bold; + -webkit-border-radius: 5px; font-size: 13px; width: 70px; } +.button:hover { background: white; color: black; } diff -r 2840389ee7f9 -r 21942fac2b4b app/site-content/css/projrev.css --- a/app/site-content/css/projrev.css Thu Aug 06 18:49:06 2009 +0530 +++ b/app/site-content/css/projrev.css Mon Aug 10 16:38:13 2009 +0530 @@ -145,7 +145,8 @@ } select { margin-left: 3%; - width: auto; + width: 313px; + overflow: scroll; } textarea { width:40%; @@ -183,6 +184,8 @@ input.micr_button { width: auto; + position: relative; + left: 22%; font: bold 1em Arial, Sans-serif; background: #FFF url(/site-content/images/gradientbg.jpg) repeat-x; color: #333; @@ -483,4 +486,12 @@ left: 22%; font: normal 1em "Trebuchet MS", Tahoma, sans-serif; color:#f00; -} \ No newline at end of file +} + +div.access-error { + padding: 3px; + margin-left: 3%; + width: auto; + font: normal 1em "Trebuchet MS", Tahoma, sans-serif; + color:#f00; +} diff -r 2840389ee7f9 -r 21942fac2b4b app/site-content/images/button-bg.png Binary file app/site-content/images/button-bg.png has changed diff -r 2840389ee7f9 -r 21942fac2b4b app/site-content/images/controls.png Binary file app/site-content/images/controls.png has changed diff -r 2840389ee7f9 -r 21942fac2b4b app/site-content/images/delete.gif Binary file app/site-content/images/delete.gif has changed diff -r 2840389ee7f9 -r 21942fac2b4b app/site-content/images/info.png Binary file app/site-content/images/info.png has changed diff -r 2840389ee7f9 -r 21942fac2b4b app/site-content/images/jquery.rating.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/site-content/images/jquery.rating.js Mon Aug 10 16:38:13 2009 +0530 @@ -0,0 +1,354 @@ +/* + ### jQuery Star Rating Plugin v3.12 - 2009-04-16 ### + * Home: http://www.fyneworks.com/jquery/star-rating/ + * Code: http://code.google.com/p/jquery-star-rating-plugin/ + * + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + ### +*/ + +/*# AVOID COLLISIONS #*/ +;if(window.jQuery) (function($){ +/*# AVOID COLLISIONS #*/ + + // IE6 Background Image Fix + if ($.browser.msie) try { document.execCommand("BackgroundImageCache", false, true)} catch(e) { }; + // Thanks to http://www.visualjquery.com/rating/rating_redux.html + + // plugin initialization + $.fn.rating = function(options){ + if(this.length==0) return this; // quick fail + + // Handle API methods + if(typeof arguments[0]=='string'){ + // Perform API methods on individual elements + if(this.length>1){ + var args = arguments; + return this.each(function(){ + $.fn.rating.apply($(this), args); + }); + }; + // Invoke API method handler + $.fn.rating[arguments[0]].apply(this, $.makeArray(arguments).slice(1) || []); + // Quick exit... + return this; + }; + + // Initialize options for this call + var options = $.extend( + {}/* new object */, + $.fn.rating.options/* default options */, + options || {} /* just-in-time options */ + ); + + // Allow multiple controls with the same name by making each call unique + $.fn.rating.calls++; + + // loop through each matched element + this + .not('.star-rating-applied') + .addClass('star-rating-applied') + .each(function(){ + + // Load control parameters / find context / etc + var control, input = $(this); + var eid = (this.name || 'unnamed-rating').replace(/\[|\]/g, '_').replace(/^\_+|\_+$/g,''); + var context = $(this.form || document.body); + + // FIX: http://code.google.com/p/jquery-star-rating-plugin/issues/detail?id=23 + var raters = context.data('rating'); + if(!raters || raters.call!=$.fn.rating.calls) raters = { count:0, call:$.fn.rating.calls }; + var rater = raters[eid]; + + // if rater is available, verify that the control still exists + if(rater) control = rater.data('rating'); + + if(rater && control)//{// save a byte! + // add star to control if rater is available and the same control still exists + control.count++; + + //}// save a byte! + else{ + // create new control if first star or control element was removed/replaced + + // Initialize options for this raters + control = $.extend( + {}/* new object */, + options || {} /* current call options */, + ($.metadata? input.metadata(): ($.meta?input.data():null)) || {}, /* metadata options */ + { count:0, stars: [], inputs: [] } + ); + + // increment number of rating controls + control.serial = raters.count++; + + // create rating element + rater = $(''); + input.before(rater); + + // Mark element for initialization (once all stars are ready) + rater.addClass('rating-to-be-drawn'); + + // Accept readOnly setting from 'disabled' property + if(input.attr('disabled')) control.readOnly = true; + + // Create 'cancel' button + rater.append( + control.cancel = $('') + .mouseover(function(){ + $(this).rating('drain'); + $(this).addClass('star-rating-hover'); + //$(this).rating('focus'); + }) + .mouseout(function(){ + $(this).rating('draw'); + $(this).removeClass('star-rating-hover'); + //$(this).rating('blur'); + }) + .click(function(){ + $(this).rating('select'); + }) + .data('rating', control) + ); + + }; // first element of group + + // insert rating star + var star = $(''); + rater.append(star); + + // inherit attributes from input element + if(this.id) star.attr('id', this.id); + if(this.className) star.addClass(this.className); + + // Half-stars? + if(control.half) control.split = 2; + + // Prepare division control + if(typeof control.split=='number' && control.split>0){ + var stw = ($.fn.width ? star.width() : 0) || control.starWidth; + var spi = (control.count % control.split), spw = Math.floor(stw/control.split); + star + // restrict star's width and hide overflow (already in CSS) + .width(spw) + // move the star left by using a negative margin + // this is work-around to IE's stupid box model (position:relative doesn't work) + .find('a').css({ 'margin-left':'-'+ (spi*spw) +'px' }) + }; + + // readOnly? + if(control.readOnly)//{ //save a byte! + // Mark star as readOnly so user can customize display + star.addClass('star-rating-readonly'); + //} //save a byte! + else//{ //save a byte! + // Enable hover css effects + star.addClass('star-rating-live') + // Attach mouse events + .mouseover(function(){ + $(this).rating('fill'); + $(this).rating('focus'); + }) + .mouseout(function(){ + $(this).rating('draw'); + $(this).rating('blur'); + }) + .click(function(){ + $(this).rating('select'); + }) + ; + //}; //save a byte! + + // set current selection + if(this.checked) control.current = star; + + // hide input element + input.hide(); + + // backward compatibility, form element to plugin + input.change(function(){ + $(this).rating('select'); + }); + + // attach reference to star to input element and vice-versa + star.data('rating.input', input.data('rating.star', star)); + + // store control information in form (or body when form not available) + control.stars[control.stars.length] = star[0]; + control.inputs[control.inputs.length] = input[0]; + control.rater = raters[eid] = rater; + control.context = context; + + input.data('rating', control); + rater.data('rating', control); + star.data('rating', control); + context.data('rating', raters); + }); // each element + + // Initialize ratings (first draw) + $('.rating-to-be-drawn').rating('draw').removeClass('rating-to-be-drawn'); + + return this; // don't break the chain... + }; + + /*--------------------------------------------------------*/ + + /* + ### Core functionality and API ### + */ + $.extend($.fn.rating, { + // Used to append a unique serial number to internal control ID + // each time the plugin is invoked so same name controls can co-exist + calls: 0, + + focus: function(){ + var control = this.data('rating'); if(!control) return this; + if(!control.focus) return this; // quick fail if not required + // find data for event + var input = $(this).data('rating.input') || $( this.tagName=='INPUT' ? this : null ); + // focus handler, as requested by focusdigital.co.uk + if(control.focus) control.focus.apply(input[0], [input.val(), $('a', input.data('rating.star'))[0]]); + }, // $.fn.rating.focus + + blur: function(){ + var control = this.data('rating'); if(!control) return this; + if(!control.blur) return this; // quick fail if not required + // find data for event + var input = $(this).data('rating.input') || $( this.tagName=='INPUT' ? this : null ); + // blur handler, as requested by focusdigital.co.uk + if(control.blur) control.blur.apply(input[0], [input.val(), $('a', input.data('rating.star'))[0]]); + }, // $.fn.rating.blur + + fill: function(){ // fill to the current mouse position. + var control = this.data('rating'); if(!control) return this; + // do not execute when control is in read-only mode + if(control.readOnly) return; + // Reset all stars and highlight them up to this element + this.rating('drain'); + this.prevAll().andSelf().filter('.rater-'+ control.serial).addClass('star-rating-hover'); + },// $.fn.rating.fill + + drain: function() { // drain all the stars. + var control = this.data('rating'); if(!control) return this; + // do not execute when control is in read-only mode + if(control.readOnly) return; + // Reset all stars + control.rater.children().filter('.rater-'+ control.serial).removeClass('star-rating-on').removeClass('star-rating-hover'); + },// $.fn.rating.drain + + draw: function(){ // set value and stars to reflect current selection + var control = this.data('rating'); if(!control) return this; + // Clear all stars + this.rating('drain'); + // Set control value + if(control.current){ + control.current.data('rating.input').attr('checked','checked'); + control.current.prevAll().andSelf().filter('.rater-'+ control.serial).addClass('star-rating-on'); + } + else + $(control.inputs).removeAttr('checked'); + // Show/hide 'cancel' button + control.cancel[control.readOnly || control.required?'hide':'show'](); + // Add/remove read-only classes to remove hand pointer + this.siblings()[control.readOnly?'addClass':'removeClass']('star-rating-readonly'); + },// $.fn.rating.draw + + select: function(value){ // select a value + var control = this.data('rating'); if(!control) return this; + // do not execute when control is in read-only mode + if(control.readOnly) return; + // clear selection + control.current = null; + // programmatically (based on user input) + if(typeof value!='undefined'){ + // select by index (0 based) + if(typeof value=='number') + return $(control.stars[value]).rating('select'); + // select by literal value (must be passed as a string + if(typeof value=='string') + //return + $.each(control.stars, function(){ + if($(this).data('rating.input').val()==value) $(this).rating('select'); + }); + } + else + control.current = this[0].tagName=='INPUT' ? + this.data('rating.star') : + (this.is('.rater-'+ control.serial) ? this : null); + + // Update rating control state + this.data('rating', control); + // Update display + this.rating('draw'); + // find data for event + var input = $( control.current ? control.current.data('rating.input') : null ); + // click callback, as requested here: http://plugins.jquery.com/node/1655 + if(control.callback) control.callback.apply(input[0], [input.val(), $('a', control.current)[0]]);// callback event + },// $.fn.rating.select + + readOnly: function(toggle, disable){ // make the control read-only (still submits value) + var control = this.data('rating'); if(!control) return this; + // setread-only status + control.readOnly = toggle || toggle==undefined ? true : false; + // enable/disable control value submission + if(disable) $(control.inputs).attr("disabled", "disabled"); + else $(control.inputs).removeAttr("disabled"); + // Update rating control state + this.data('rating', control); + // Update display + this.rating('draw'); + },// $.fn.rating.readOnly + + disable: function(){ // make read-only and never submit value + this.rating('readOnly', true, true); + },// $.fn.rating.disable + + enable: function(){ // make read/write and submit value + this.rating('readOnly', false, false); + }// $.fn.rating.select + + }); + + /*--------------------------------------------------------*/ + + /* + ### Default Settings ### + eg.: You can override default control like this: + $.fn.rating.options.cancel = 'Clear'; + */ + $.fn.rating.options = { //$.extend($.fn.rating, { options: { + cancel: 'Cancel Rating', // advisory title for the 'cancel' link + cancelValue: '', // value to submit when user click the 'cancel' link + split: 0, // split the star into how many parts? + + // Width of star image in case the plugin can't work it out. This can happen if + // the jQuery.dimensions plugin is not available OR the image is hidden at installation + starWidth: 16//, + + //NB.: These don't need to be pre-defined (can be undefined/null) so let's save some code! + //half: false, // just a shortcut to control.split = 2 + //required: false, // disables the 'cancel' button so user can only select one of the specified values + //readOnly: false, // disable rating plugin interaction/ values cannot be changed + //focus: function(){}, // executed when stars are focused + //blur: function(){}, // executed when stars are focused + //callback: function(){}, // executed when a star is clicked + }; //} }); + + /*--------------------------------------------------------*/ + + /* + ### Default implementation ### + The plugin will attach itself to file inputs + with the class 'multi' when the page loads + */ + $(function(){ + $('input[type=radio].star').rating(); + }); + + + +/*# AVOID COLLISIONS #*/ +})(jQuery); +/*# AVOID COLLISIONS #*/ diff -r 2840389ee7f9 -r 21942fac2b4b app/site-content/images/loading.gif Binary file app/site-content/images/loading.gif has changed diff -r 2840389ee7f9 -r 21942fac2b4b app/site-content/images/login-page-bg.jpg Binary file app/site-content/images/login-page-bg.jpg has changed diff -r 2840389ee7f9 -r 21942fac2b4b app/site-content/images/purrBottom.png Binary file app/site-content/images/purrBottom.png has changed diff -r 2840389ee7f9 -r 21942fac2b4b app/site-content/images/purrClose.png Binary file app/site-content/images/purrClose.png has changed diff -r 2840389ee7f9 -r 21942fac2b4b app/site-content/images/purrTop.png Binary file app/site-content/images/purrTop.png has changed diff -r 2840389ee7f9 -r 21942fac2b4b app/site-content/images/star.gif Binary file app/site-content/images/star.gif has changed diff -r 2840389ee7f9 -r 21942fac2b4b app/site-content/js/jquery.chainedSelects.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/site-content/js/jquery.chainedSelects.js Mon Aug 10 16:38:13 2009 +0530 @@ -0,0 +1,85 @@ +/** +* Chained Selects for jQuery +* Copyright (C) 2008 Ziadin Givan www.CodeAssembly.com +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see http://www.gnu.org/licenses/ +* +* +* settings = { usePost : true, before:function() {}, after: function() {}, default: null, parameters : { parameter1 : 'value1', parameter2 : 'value2'} } +* if usePost is true, then the form will use POST to pass the parameters to the target, otherwise will use GET +* "before" function is called before the ajax request and "after" function is called after the ajax request. +* If defaultValue is not null then the specified option will be selected. +* You can specify additional parameters to be sent to the the server in settings.parameters. +* +*/ +jQuery.fn.chainSelect = function( target, url, settings ) +{ + return this.each( function() + { + $(this).change( function( ) + { + settings = jQuery.extend( + { + after : null, + before : null, + usePost : false, + defaultValue : null, + parameters : {'_id' : $(this).attr('id'), '_name' : $(this).attr('name')} + } , settings); + + settings.parameters._value = $(this).val(); + + if (settings.before != null) + { + settings.before( target ); + } + + ajaxCallback = function(data, textStatus) + { + $(target).html("");//clear old options + data = eval(data);//get json array + for (i = 0; i < data.length; i++)//iterate over all options + { + for ( key in data[i] )//get key => value + { + $(target).get(0).add(new Option(data[i][key],[key]), document.all ? i : null); + } + } + + if (settings.defaultValue != null) + { + $(target).val(settings.defaultValue);//select default value + } else + { + $("option:first", target).attr( "selected", "selected" );//select first option + } + + if (settings.after != null) + { + settings.after(target); + } + + $(target).change();//call next chain + }; + + if (settings.usePost == true) + { + $.post( url, settings.parameters, ajaxCallback ); + } else + { + $.get( url, settings.parameters, ajaxCallback ); + } + }); + }); +}; \ No newline at end of file diff -r 2840389ee7f9 -r 21942fac2b4b app/site-content/js/jquery.colorbox-min.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/site-content/js/jquery.colorbox-min.js Mon Aug 10 16:38:13 2009 +0530 @@ -0,0 +1,3 @@ +// ColorBox v1.2.7 - a full featured, light-weight, customizable lightbox based on jQuery 1.3 + +(function(B){var G,V,W,d,z,k,b,F,c,Q,D,e,s,j,m,P,l,H,t;var X,i,g,a,p,A,T,w,I,q="colorbox",o="hover";var y,f,R,L,K,J,r,M;var x="cbox_open",O="cbox_load",u="cbox_complete",h="cbox_close",n="cbox_closed";var C={transition:"elastic",speed:350,width:false,height:false,initialWidth:"400",initialHeight:"400",maxWidth:false,maxHeight:false,resize:true,inline:false,html:false,iframe:false,photo:false,href:false,title:false,rel:false,opacity:0.9,preloading:true,current:"image {current} of {total}",previous:"previous",next:"next",close:"close",open:false,overlayClose:true,slideshow:false,slideshowAuto:true,slideshowSpeed:2500,slideshowStart:"start slideshow",slideshowStop:"stop slideshow"};B(function(){R()});function N(Y){if(Y.keyCode==37){Y.preventDefault();H.click()}else{if(Y.keyCode==39){Y.preventDefault();l.click()}}}function E(Y,Z){Z=Z=="x"?document.documentElement.clientWidth:document.documentElement.clientHeight;return(typeof Y=="string")?(Y.match(/%/)?(Z/100)*parseInt(Y,10):parseInt(Y,10)):Y}function v(Y){return T.photo?true:Y.match(/\.(gif|png|jpg|jpeg|bmp)(?:\?([^#]*))?(?:#(.*))?$/i)}function U(){for(var Y in T){if(typeof(T[Y])=="function"){T[Y]=T[Y].call(p)}}}B.fn.colorbox=function(Z,Y){if(this.length){this.each(function(){var aa=B(this).data(q)?B.extend({},B(this).data(q),Z):B.extend({},C,Z);B(this).data(q,aa).addClass("cboxelement")})}else{B(this).data(q,B.extend({},C,Z))}B(this).unbind("click.colorbox").bind("click.colorbox",function(ab){p=this;T=B(p).data(q);U();B().bind("keydown.cbox_close",function(ac){if(ac.keyCode==27){ac.preventDefault();t.click()}});if(T.overlayClose===true){G.css({cursor:"pointer"}).one("click",M)}p.blur();I=Y||false;var aa=T.rel||p.rel;if(aa&&aa!="nofollow"){c=B(".cboxelement").filter(function(){var ac=B(this).data(q).rel||this.rel;return(ac==aa)});A=c.index(p);if(A<0){c=c.add(p);A=c.length-1}}else{c=B(p);A=0}if(!w){B.event.trigger(x);t.html(T.close);G.css({opacity:T.opacity}).show();w=true;K(E(T.initialWidth,"x"),E(T.initialHeight,"y"),0);if(B.browser.msie&&B.browser.version<7){Q.bind("resize.cboxie6 scroll.cboxie6",function(){G.css({width:Q.width(),height:Q.height(),top:Q.scrollTop(),left:Q.scrollLeft()})})}}r();L();ab.preventDefault()});if(Z&&Z.open){B(this).triggerHandler("click.colorbox")}return this};R=function(){function Y(Z){return B('
')}Q=B(window);V=B('
');G=Y("Overlay").hide();W=Y("Wrapper");d=Y("Content").append(D=Y("LoadedContent").css({width:0,height:0}),e=Y("LoadingOverlay"),s=Y("LoadingGraphic"),j=Y("Title"),m=Y("Current"),P=Y("Slideshow"),l=Y("Next"),H=Y("Previous"),t=Y("Close"));W.append(B("
").append(Y("TopLeft"),z=Y("TopCenter"),Y("TopRight")),B("
").append(k=Y("MiddleLeft"),d,b=Y("MiddleRight")),B("
").append(Y("BottomLeft"),F=Y("BottomCenter"),Y("BottomRight"))).children().children().css({"float":"left"});B("body").prepend(G,V.append(W));if(B.browser.msie&&B.browser.version<7){G.css("position","absolute")}d.children().addClass(o).mouseover(function(){B(this).addClass(o)}).mouseout(function(){B(this).removeClass(o)}).hide();X=z.height()+F.height()+d.outerHeight(true)-d.height();i=k.width()+b.width()+d.outerWidth(true)-d.width();g=D.outerHeight(true);a=D.outerWidth(true);V.css({"padding-bottom":X,"padding-right":i}).hide();l.click(f);H.click(y);t.click(M);d.children().removeClass(o)};K=function(ab,aa,Z,ac){var ad=document.documentElement.clientHeight;var af=ad/2-aa/2;var ae=document.documentElement.clientWidth/2-ab/2;if(aa>ad){af-=(aa-ad)}if(af<0){af=0}if(ae<0){ae=0}af+=Q.scrollTop();ae+=Q.scrollLeft();ab=ab-i;aa=aa-X;W[0].style.width=W[0].style.height="9999px";function ag(ah){z[0].style.width=F[0].style.width=d[0].style.width=ah.style.width;s[0].style.height=e[0].style.height=d[0].style.height=k[0].style.height=b[0].style.height=ah.style.height}var Y=(V.width()===ab&&V.height()===aa)?0:Z;V.dequeue().animate({height:aa,width:ab,top:af,left:ae},{duration:Y,complete:function(){ag(this);W[0].style.width=(ab+i)+"px";W[0].style.height=(aa+X)+"px";if(ac){ac()}},step:function(){ag(this)}})};J=function(ad){if(!w){return}Q.unbind("resize.cbox_resize");var ab=T.transition=="none"?0:T.speed;D.remove();D=B(ad);var Z;var aj;function ah(){if(T.width){Z=maxWidth}else{Z=maxWidth&&maxWidth0?ae:0)+"px"}function ai(am){var al=Z+a+i;var an=aj+g+X;K(al,an,am,function(){if(!w){return}if(B.browser.msie){if(Y){D.fadeIn(100)}V.css("filter","")}d.children().show();B("#cboxIframeTemp").after("