text:
Business of Climate
IMF's Lagarde warns against trade and currency wars
Updated / Thursday, 11 Oct 2018 09:21
IMF chief Christine Lagarde has urged countries to 'de-escalate' trade conflicts and fix global trading rules instead of abandoning them
International Monetary Fund Managing Director Christine Lagarde has warned countries against engaging in both trade and currency wars.
She said these wars would hurt global growth and imperil "innocent bystanders."
Formally launching the IMF and World Bank annual meetings on the Indonesian island of Bali, Ms Lagarde urged countries to "de-escalate" trade conflicts and fix global trading rules instead of abandoning them.
The US and China have slapped tit-for-tat tariffs on hundreds of billions of dollars of each other's goods over the past few months, rattling financial markets as investors worry that the escalating trade conflict could knock global trade and investment.
Share markets in Asia plunged to a 19-month low in earlier trade after Wall Street's worst losses in eight months led to broader risk aversion, partly due to the heated global trade tensions as well as rapidly rising dollar yields.
"We certainly hope we don't move in either direction of a trade war or a currency war. It will be detrimental on both accounts for all participants," Christine Lagarde told a news conference.
"And there would also be lots of innocent bystanders," including countries that are part of China's supply chain.
In recent weeks, US Treasury officials have expressed concerns about China's weakened yuan as the department prepares its semi-annual report on currency manipulation.
US President Donald Trump has accused China of deliberately manipulating its currency to gain a trade advantage, claims Beijing has consistently rejected.
US Treasury Secretary Steven Mnuchin met with People's Bank of China Governor Yi Gang today on the sidelines of the IMF-World Bank meeting.
"We discussed important economic issues," Mnuchin said of their meeting on Twitter.
Christine Lagarde weighed into the debate on Thursday, saying that yuan weakness against the dollar was driven by the greenback's strength as the US Federal Reserve hikes interest rates. Against a basket of currencies, the yuan has depreciated less.
"We have supported the move of China towards (currency) flexibility and we want to encourage the authorities to continue on this path going forward," she said.
China's currency has faced strong selling pressure this year, losing over 8% between March and August at the height of market worries, though it has since pared losses as authorities stepped up support measures.
The IMF chief said later that she believed Chinese authorities were taking steps to maintain growth, stability and investor confidence amid the trade conflict, but faced a "complicated" balancing act to keep its fiscal situation under control.
World Bank President Jim Yong Kim
World Bank President Jim Yong Kim also warned against an escalation of the trade row, saying that the development lender's agenda depended on strong trade flows and that there would be a clear hit to growth if all countries followed through on their trade threats.
The meetings, attended by more than 19,000 delegates, showed no sign of disruption from an offshore earthquake early this morning between Bali and Java island that killed three people and damaging some buildings.
Kim pledged World Bank support for Indonesia in the wake of a series of earthquakes, including financing support for rebuilding of critical assets such as schools, hospitals and roads, as well as damaged housing settlements.
Accreditation: Reuters


Lubriderm, known for their vast array of skincare products developed by dermatologists, has introduced a 3-in-1 lotion for Men. This new product boasts the ability to specifically take care of the Body and Face as well as cover your Post-Shave needs. It comes in two versions, "light fragrance" (pictured) and "fragrance free".
They both performed well as moisturizers for my body and face, however I wasn't impressed with it's "Post-Shave" performance. In a bind-yes, but as your daily aftershave balm, I would have to say pass.
So all in all, I think that it's a very good 2-in-1 lotion that not only has a great price tag (less than $7), but because it coats well, will also allow for it's 16oz to last you a while!
Of the two, I preferred the lightly fragranced version the best. Give it a shot and let me know how it works for you.


Kataz smoothed her pleated skirt as she waited for the Library Faerie to finish posting the day's crossword. After Xandra's disastrous . . . departure . . . openings at the Faerieland Library were even more scarce. Kataz had been on a waiting list since before Faerieland fell. If she messed up this interview, Kataz doubted she'd have another chance to earn a spot working in the library or even the Faerieland bookshop.
Certain her skirt was perfectly smooth, Kataz moved on to stroking her ears and smoothing the fur on her paws. First one, then the other. Being a Cybunny, Kataz was more used to the cooler climes of Northern Neopia. Even her home on Bread Street in Neopia Central was sometimes uncomfortable. Faerieland settled much farther south when it fell, just a short walk from the Lost Dessert. Sitting in the Library Faerie's office, Kataz was beginning to feel uncomfortably warm.
With a caring smile that soothed some of Kataz's nerves, the Library Faerie beckoned the Cybunny into her office.
From behind her desk the faerie looked at Kataz from over her glasses as she settled herself into a plush chair on the opposite side of the desk.
The Library Faerie flipped through Kataz's thick resume. "I see you're a regular visitor to the library and Faerieland's bookshop. You also have an impressive set of references from the Faerieland Employment Agency."
Kataz smiled nervously. "I love books. It's always been my dream to work in the Faerieland Library."
The faerie nodded again. "I have no doubt you have the technical background to work here. I worry, though, that you lack the practical experience our staff demands. You've probably guessed as much from Xandra's exploits, but Faerieland does not have what you would call a typical library."
Kataz blinked unsure if she was meant to agree or take the opportunity to denounce Xandra's villainous deeds. She nodded demurely hoping that would cover whatever reaction the Library Faerie hoped to see.
"If we were hiring solely on expertise, the job would be yours. As it stands, I'd like to propose a small test. To be sure you understand what working for the Faerieland Library will entail as much as to be sure you're up for it."
Kataz nodded, confident in her abilities. Nothing could be as strange as her last job hunting down rag dolls in Mystery Island. Even with Nayha's help it had taken hours to navigate the labyrinthine stalls of the island Trading Post.
With complete calm, Kataz replied, "A small test won't be a problem. Once it's over I'm sure you'll agree I'm the best candidate for this position."
Kataz's interview with the Library Faerie had been a scant three hours earlier. Her unfailing confidence that she could complete the Library Faerie's test was already beginning to feel like the height of folly--not to mention a little bit arrogant.
It had seemed simple enough when the Library Faerie explained what she had in mind. All Kataz had to do was collect an overdue book from Naia, the Fountain Faerie. Simple.
Upon arriving at the Rainbow Fountain, Kataz realized her mistake.
Naia smiled at the Cybunny beatifically. "Alas, my fountain is not working properly right now," she said as she waved a hand behind her to indicate the dry fountain.
"I'm actually not here about the fountain at all," Kataz said politely. "I'm here to collect an overdue library book. You checked a copy of the Faerie Colourpedia out of the Faerieland Library nearly four months ago. The Library Faerie sent me to collect it and return it on your behalf."
Naia pouted. "But it's so boring here without my fountain working. No one has completed one of my quests in ages. If you take my book I'll be dreadfully bored," she whined.
Kataz pursed her lips. She did not mention that things would be more entertaining if Naia would just hire someone to fix her fountain permanently. Nor did she mention that Matt would probably be more than happy to take a break from surfing Neopia's sewers to look at the fountain. Kataz had a feeling none of that was the actual problem. She suspected Naia wanted a challenge. She suspected she knew exactly what Naia wanted for the book.
Taking a deep breath, Kataz said, "What if I complete one of your quests? One quest item in exchange for your overdue book."
One of Naia's eyebrows quirked up. "Yes," she drawled. "I suppose that would be fair." In a more forceful voice she said, "Neopian, bring me Spring Time Female Krawk Dress and you shall have your book."
The Fountain Faerie then proceeded to ignore Kataz completely which the Cybunny took as her cue to leave.
Kataz knew from experience that Unis Clothing would likely be too crowded and busy to help her properly. Instead she decided to start at the Almost Abandoned Attic. Neovia was walking distance from Faerieland and while the attic's stock was erratic, it was also known as a shopping destination for anyone looking for obscure items at a dramatically lower price.
Kataz shuddered as she walked into the attic--the ghost Aisha who ran the attic always made her nervous.
Before she could properly introduce herself, the Aisha appeared "Oops," she said in her eerie voice. "We just ran out of items."
"That's okay," Kataz said immediately, "I just wanted to know if you think you'll be getting Spring Time Female Krawk Dress in stock anytime soon."
The ghost smiled. "Perhaps," she said cryptically.
"Is that a yes or a no?"
"It's a maybe. I do occasionally take special orders. But not for my health and certainly not for free."
Kataz pursed her lips. She could guess where this path lead. "What, exactly, do you want?"
The Aisha adjusted her collar. "It's incredibly dreary here, don't you think? I'm rather fond of neggs. Can't stand the taste, of course, but I think they're quite decorative, don't you?"
Kataz refrained, just barely, from rolling her eyes. "How many neggs for the dress?"
"Oh, let's make it a round dozen," the ghost said with a purse of her lips.
"Fine," she said through clenched teeth as she stomped out to procure passage to Terror Mountain.
As she wove through the Ice Caves on her way to the Neggery, Kataz reasoned she was lucky to have fur. At least she hadn't needed to stop for a coat. The Library Faerie's test was already taking much longer than she had expected.
Kataz was relieved to find Kari at her station upon arriving at the Neggery. "Hello," she said, "I'd like to buy a dozen neggs."
Kari pulled an oversized calculator from behind an oversized negg bush. "Egg-cellent," she said to herself as she began to punch in numbers.
"Decorative neggs," Kataz added belatedly.
Kari only nodded without looking up from her calculator. At length she turned back to the Cybunny and said, "That will be 200,342 neopoints."
"What?!" Kataz exploded. "That's absolutely ridiculous." She could have bought the Spring Time Female Krawk dress herself for that price.
Kari shrugged. "Supply and demand."
"Well, I demand a better price," Kataz said with furrowed eyebrows.
Kari crossed her arms. "I've been looking for a new petpet. Bring me a Noak and we can talk. Maybe."
Kataz smiled at the first bit of good luck she had had all day. "I don't suppose you'd have a spare bucket?" she asked.
Kataz had been fishing at Ye Olde Fishing Vortex in the Maraquan Ruins for years--even before her youngest sister Druyanava had been born. Nerc and Nayha enjoyed fishing as much as Kataz herself did. But Kataz was the one with a fishing skill well above 250 and a special knack for attracting Maraquan petpets.
With the proper bait, Maraquan petpets--especially ones as perpetually hungry as Noaks--were easy to catch. It was almost as easy as fishing in a barrel . . . instead of an underwater lake. Either way, Kataz had soon retrieved the request Noak who burbled happily as she dipped him into her borrowed bucket.
The Noak began turning tight circles inside the bucket as Kataz nodded to the regulars on her way out. She returned her fishing rod to the bait shop and made her way out of Maraqua.
Kataz's second trip to Terror Mountain was far less enjoyable thanks to her wet fur and clothes. Reasoning that she could soon Kataz hopped briskly back to the Neggery where she found a very bored Kari waiting for her return.
Kari yawned enormously. "I was just getting ready to close for my afternoon break," she said with a stretch.
Kataz set the bucket down on the desk in front of Kari, tired of small talk. "One Noak for one dozen decorative neggs."
Kari grinned. "He's so cute!" she squealed happily. With a clap of her hands she scooped up the Noak and placed him in a grander, large Negg-shaped tank. "Let me get you some powerful, magical neggs!"
"Decorative ones would be better," Kataz called after the Negg Faerie.
"Well, of course. All of my neggs are egg-cellent," Kari called from the cabinet she had crawled inside.
Kataz watched the Noak swim in his tank while she waited. The tank was decorated with miniature neggs that the Noak was systematically eating to sate its appetite. Kataz decided it wasn't worth mentioning to Kari.
The trek from Terror Mountain back to the Almost Abandoned Attic seemed to take forever. On the bright side, by the time she barged into the attic Kataz' fur and clothes were completely dry.
The ghost Aisha smiled as she directed Kataz to deposit the neggs at various points throughout the attic.
"My, my, my, these neggs certainly do liven up the place!" the ghost Aisha said with a laugh that came uncomfortably close to a cackle. Kataz was glad to collect her Spring Time Female Krawk Dress and leave.
"Greetings, Neopian!" Naia bellowed as Kataz returned.
Kataz held the dress up in front of her. "I have your Spring Time Female Krawk Dress," she said triumphantly.
"Thank you so much! You're so kind to me," Naia said as she took the dress and tossed it atop a pile behind her fountain. "You may come visit me at my Rainbow Fountain any time! I'll be happy to award you with a brand new colour!"
"Actually, I like being Christmas," the Cybunny said as she stroked her red and green mane. "But I believe you owe me an overdue library book."
The Fountain Faerie stared at Kataz blankly for an excruciating moment before she nodded. "Of course."
She turned to dig through her pile of expensive wearables, tossing them about as if they were cheap buyables. Kataz shook her head and reminded herself it was best not to chastise Naia--she was probably friends with Boochi and Kataz certainly did not want to be painted Baby.
Turning, Naia tossed the Faerie Colourpedia to Kataz. "Here you go. And it's only three months overdue. I'm getting better at this!" she said with a grin.
Kataz blinked, remembering that Naia was related to Marina from the Healing Springs.
"I thank you and I'm sure the Faerieland Library thanks you as well," Kataz said with a wave.
"Fishing is really just a matter of using the right bait," Kataz explained back at the library, "so from there it was easy to get a Noak for the neggs to trade for the dress to bring to Naia. And now I have your book," she said handing the book carefully to the Library Faerie.
The faerie smiled. "I think you're going to be an excellent fit here. Let's talk about when you can start."
Kataz beamed. She couldn't wait to tell her family about her new job.
Give me a hand pls?
To all those who've worked in a kitchen, this is for you.
Dartenne always keeps his promises.
"Thunder must have been collecting disgruntled recruits for years. I think he's got a bit of a Xandra complex."


text:
Tag Archives: Pork
China's Pork Prices Expected to Remain High in 2016
Apr 12, 2016 Meat (Pork)Pork, Prices
Pork prices will remain high this year, but will not soar, a spokesperson for the Ministry of Commerce (MOC) said on Thursday [7 April 2016]. The average wholesale pork price hit 25.34 yuan (3.92 U.S. dollars) per kg last week, up 0.4 percent from the previous week to the highest point since October 2011, Shen
China's Domestic Hog Prices Reach Their Highest Level Since 2011
Mar 28, 2016 Meat (Pork)Hogs, Pork, Prices
Domestic hog prices in March, normally a low season for pork consumption, surged to the highest level since mid-2011. Higher pork prices are pushing up restaurants' costs, but the impact on consumers' daily lives is limited, shoppers told the Global Times on Wednesday [23 March 2016]. As of March 9, the price of live hogs
Hong Kong Listed Meat Processor Briefly Suspends Shares Amid Loan Default
Mar 27, 2016 Meat (General)Jiangsu, Pork
China Yurun Food Group said that a default by a unit on short-term notes worth 500 million yuan ($77 million) has in turn triggered other provisions that require the immediate repayment of debt worth 1.45 billion yuan, Reuters reported on Tuesday [22 March 2016]. The unit, Nanjing Yurun Food Co, has arranged partial repayment of
Anhui Province Breeds and Markets Local Black Hog Variety
Mar 27, 2016 Meat (Pork)Anhui, Black hog, Pork
Consumers with the ability to pay a premium for organic food are encouraging pig breeders in the mountains of eastern China's Anhui province to embrace new business opportunities that are expected to boost their incomes. On a mountain about 1,000 meters above sea level, breeder He Xianglin has tapped a spring with "really sweet" water
Pork Prices at Xinfadi, Beijing's Top Wholesale Market, Spike
Mar 25, 2016 Meat (Pork)Beijing, Pork, Prices, Wholesale Markets
Last month [February 2016], pork prices in Beijing's major wholesale market, Xinfadi, rose by nearly 60 percent year-on-year. "A number of pig breeders exited the market years ago amid sluggish prices. The price hike is good for producers, but it'll cut consumption in the long run." Wang Bo, feed trader in Mianyang, Sichuan province "The
China Grants Exports Licenses to Belgian Pork Producers
Mar 15, 2016 Meat (Pork)Belgium, Pork
A Belgian pork producer has been given approval to export an estimated 56,000 tonnes a year to China, which Belgium's agriculture minister says will give a major boost to the country's farming sector. Belgian leading pork company Noordvlees Van Gool, along with other local pork companies welcomed on Tuesday [8 March 2016] Chinese Ambassador Qu
Australian Swine Veterinarian Company Plans IPO to Fund Export Trade with China
Nov 29, 2015 Meat (Pork)Australia, Beef, Cattle, Dairy, IPO, Pork
An Australian pig veterinarian plans to raise A$40 million ($29 million) in an IPO, saying he plans to use the cash to buy 12 livestock health businesses and capitalize on an export boom tipped to follow a trade deal with China. Companies linked to Australian agriculture exports are defying a slowdown in IPO activity and
Tysons Foods to Spend US$16 Million in 2016 on Chinese Marketing
Nov 24, 2015 Meat (Poultry)Pork, Poultry, Tyson Foods, USA
Tyson Food Inc, the world's largest supplier of poultry, beef and pork products, plans to spend at least 100 million yuan ($16 million) on promoting its brand in China next year. Bill Mayer, vice-president and general manager of Tyson China, said the 80-year-old company views the market as offering "phenomenal" potential. In July, Tyson revealed
NDRC Lowers Break-Even Ratio for Chinese Pig Farmers
Nov 16, 2015 Meat (Pork)Hogs, Pork
Chinese farmers can avoid losing money in raising pigs as long as the live pig price is 5.5 times of maize price, an official said at a news briefing on Thursday [5 November 2015]. The break-even point, or ratio between pig price and maize price, has changed to 5.5:1 from the former 6:1, said Xu
Shandong-based Meat Company to Purchase a 45% Stake in Australia's 4th Largest Meat Processor
Nov 9, 2015 Meat (Beef)Australia, Beef, Investment, Pork, Shandong
Delisi Food Co, a Shenzhen-listed food supplier, has bought a 45 percent stake in Australia's fourth-largest meat processor as beef imports into China continue to rise. The investment in Bindaree Beef Group is estimated to be worth $105 million, according to Australian press reports. The deal will enable the Australian company to use Delisi's extensive

redpajama_set_name: RedPajamaCommonCrawl


I'm doing two jobs and actively working on local club admin work.
I think I need to keep 5+ lastpass accounts.
one fore work place#1, one fore work place#2, one for my club, one for my home, one for the holidaying and one for the logins what I'm not sharing with my kids.
Thing is some of the time there will be people working with me behind the shoulder, and at my home computer I'd like to leave last pass logged in all the time.
if sub logins can't view passwords or access console, we only need to login from master login when we need to modify/organize passwords.
We can prevent login from master login from unsafe environments.


CEDAR FALLS, Iowa – Jim Wohlpart has been named provost and executive vice president for academic affairs at the University of Northern Iowa, pending official approval by the Board of Regents, State of Iowa. Wohlpart is currently dean of Undergraduate Studies and professor of English at Florida Gulf Coast University. He will assume his new duties at UNI on May 31.
"Dr. Wohlpart has an extensive background in academic leadership," said UNI President Bill Ruud. "He has engaged and advanced student success and academic excellence through developing special skills, knowledge and ability at Florida Gulf Coast University. I am excited that he will be bringing those skills and expertise to the University of Northern Iowa."
Wohlpart earned his Ph.D. in English and B.A. in English and philosophy from the University of Tennessee. He earned an M.A. in English from Colorado State University. During his 21 years at Florida Gulf Coast University, Wohlpart held the positions of chair of the Division of Humanities and Arts and associate dean for planning and assessment in the College of Arts and Sciences. He participated in the development of the Liberal Studies degree and the Interdisciplinary Core, and he was instrumental in developing the First Year and Transition Experience.
"I am deeply honored to be joining the faculty, staff and students at the University of Northern Iowa at such an important time in the history of higher education," said Wohlpart. "With its focus on transformative education and rich community partnerships, UNI is a leader in providing innovative learning experiences that prepare students for professional careers, engagement with their communities and lifelong learning. I look forward to joining President Ruud and the UNI community to advance the long trajectory of academic excellence and student success that make this institution a special place."
The provost and executive vice president provides vision for academic excellence, guides the academic planning and assessment of university academic programs, and provides administrative leadership and organization for all the academic components of the university.
Wohlpart replaces Michael Licari, who has served in an interim position since 2014.


Obituary for Pauline E. (Crawford) Heathcote | Feiser Funeral Home, Inc.
Pauline E. (Crawford) Heathcote, 84, of Merritt Island, FL, formerly of York County, passed away on Saturday, March 16, 2019, with her husband of 65 years, Dennis, by her side.
Pauline was born July 17, 1934, in Abbottstown, the daughter of the late Harry and Carriemae (Nelson) Crawford.
Pauline's first job was at National Gypsum Co in York, where she met her future husband Dennis. She retired from Faith Lutheran Church in Merritt Island, FL, in 1998, after working there for 26 years. She also taught Sunday School, and served for two years as secretary of the Church Council at Faith Lutheran. After retirement, she became a member of the Caring Ministry, and served on the Altar Committee.
In addition to her husband Dennis, Pauline is survived by two sons, Lynn C. Heathcote and Daniel R. Heathcote and his wife Lori, two daughters, Barbara J. Gell and her husband Steve, and Susan A. Curtis and her husband Dwain, six grandchildren, Nicole and Tyler Rank, Justin Gell, Cory and Amanda Heathcote, and Sara Curtis, two sisters, Janice Brady and Brenda Farley, and two brothers, Dale and David Crawford.
Funeral services will be held on Thursday, March 21, 2019 at 10 AM at St. John's Lutheran Church, 100 E. Water St, Abbottstown, with Rev. Shawn Berkebile officiating. Burial will be in the church cemetery. A viewing will be held on Wednesday from 6-8 PM at the Feiser Funeral Home, Inc, 302 Lincoln Way West, New Oxford. Memorial contributions may be made to the American Cancer Society. Memories may be shared at www.feiserfuneralhome.com.


A Company Logo Design always looks after the company needs of individuals. With the help of this logo design Sydney al the individuals will be able to obtain most suiting outcomes as per their needs. Logo design Sydney is specially made for the special requirements of individuals that are always coming all over the Sydney. A Logo Design can instantly boost the business of the website. logo design plays a very huge role when it comes to increasing ranking of the website. Sydney logo design makes various rules and regulations for the individuals that are present all over the Sydney. This Sydney logo design can prove to be very advantageous when it comes to maintain various types of rules all over the Sydney. Sydney logo design works for providing customized solutions to various needs of individuals that are coming throughout the process. Logo is the very first thing that is usually seen by all at the time of carrying out visit on website.
This logo in short makes a very brief note of the overall content of the website. Various changes keep on occurring in the process. Keeping up with all these changes is highly essential to look after all the changing needs and requirements of the individuals that usually take place in the entire process of working. This logo has to be a unique symbol for the website which very briefly describes the entire content of the website. Everything gets sorted out in best possible manner to suit various requirements of the individuals.


text:
"With a Company-Wide Space Between the Two" - Two Lexington Companies?
An analysis of the various accounts and reports of the Battle of Lexington suggest that the battlefield must have been a visual mess as the British column approached. The combination of darkness, spectators gathered in small clusters and militiamen coming and going from the common must have contributed to Major Pitcairn and Lieutenant Sutherland's false impression that a large number of armed provincials were drawn up on the common.
However, despite the confusion, there is an account that suggest Captain Parker's Company was sufficiently disciplined and drawn up in military order. Specifically, Ensign Henry De Berniere of the 10th Foot provided an account of the Lexington men being drawn up in two divisions "with a company-wide space between the two."
Of course, based upon De Berniere's account, this begs the question: is it possible that there were two companies of Lexington militia on the common on April 19th? Most likely the answer is "no".
"Lexington Green" by Don Troiani
Almost a month after the battle Daniel Harrington recounted that when the militia mustered earlier in the morning, "the train band or Militia, and the alarm men (consisting of the aged and others exempted from turning out, excepting upon alarm) repaired in general to the common, close in with the meeting-house, the usual place of parade; and there were present when the roll was called over about one hundred and thirty of both."
Unfortunately, Harrington is silent as to whether the alarm list and training band mustered together or as separate entities. When the militia assembled for a second time just before the Battle of Lexington, Harrington makes no reference to a second company. Instead, those who mustered are merely referred to as "the remains of the company."
Likewise, not a single deposition signed by spectators and Lexington militiamen makes reference to more than one company mustering on the field.
Of course, Loyalist and Boston resident George Leonard, who accompanied Percy's relief column as a scout and was not a witness to the Battle of Lexington, indirectly suggested in his deposition that another company, perhaps unattached to Parker's Company, was nearby.
"That being on horseback . . .he several times went forward of the Brigade; in one of which excursions he met with a Countryman who was wounded supported by two others who were armed . . .the Deponent then asked what provoked [the regulars] to do it . . . he said that Some of our people upon the Regulars . . . he said further that it was not the Company he belonged to that fired but some of our Country people that were on the other Side of the Road."
However, Leonard's deposition is in direct contradiction with a statement given by James Marr, of the 4th Regiment of Foot, to the Reverend William Gordon. According to Marr, "when they and the others were advanced, Major Pitcairn said to the Lexington Company, (which, by the by, was the only one there), stop, you rebels! And he supposed that the design was to take away their arms."
So what did the ensign actually see? Henry De Berniere probably observed a well drilled militia company that had been organized into platoons or divisions by its commanding officer.
There is no doubt Parker and his men were actively drilling in the months leading up to the battle. Period accounts document at least six occasions, as recent as the night before the battle, that the Lexington Company was drilling and performing maneuvers.
Interestingly, one period drill available to Captain Parker instructs officers of companies with more than forty men to divide the company into divisions, "in which case the captain leads the first, and the ensign the third, the lieutenant bringing up the rear. In general, the rule is, that the chief or commanding officer leads the whole, the second in command brings up the rear and the others lead the intermediate divisions."
It is likely that Captain Parker followed this instruction and organized his company into "divisions" on the Lexington Common. This decision is corroborated by Lieutenant Colonel Smith's report on the engagement. "I understand, from the report of Major Pitcairn, who was with them, and from many officers, that they found on a green close to the road a body of the country people drawn up in military order, with arms and accoutrement, and, as appeared after, loaded."
It's Too Hot...
It's too hot to blog today. So we'll be at the beach...playing in the sand...in Victorian clothing.
Image of a family with the Plum Island Lighthouse (Newburyport, Massachusetts) behind them (c.1900). This particular lighthouse was built in 1898.
Shrub, Rattle Skull and Fish House Punch! (Oh My!)
Admittedly, the nerds of Historical Nerdery have been busy dealing with their students and moody teenage soccer players. So our apologies for the delay in posting.
To make amends, and in recognition of the warm weather that will arrive in Massachusetts later this week, here are some historically themed cocktail recipes we highly recommend!
2 oz. of dark rum
½ oz. of Shrub syrup
NOTE: To make the shrub syrup: In a medium bowl, mash the berries with the sugar and let sit for one and a half hours. Strain through a fine sieve into a clean bowl, pressing on the fruit to extract as much liquid as possible. Stir in vinegar and pour into a bottle or jar and refrigerate. The syrup can be kept in the fridge for up to two months.
Rattle Skull
2 oz. of brandy
1 pint of dark beer
Fish House Punch
3/4 ounce dark rum
3/4 ounce Cognac
3/4 ounce peach brandy
1/4 ounce fresh lime juice
1/2 ounce fresh lemon juice
1 lime slice
1 maraschino cherry
5 oz of beer
5 oz of ginger beer or ginger ale
1 tsp of brown sugar
2 oz. of golden/dark rum
Whole nutmeg
Combine egg, sugar, and rum in a shaker with ice. After shaking hard, strain into a chilled glass. Garnish with freshly grated nutmeg.
And why not a 20th century bonus recipe as well...
1.5 oz white rum
1.5 oz pineapple juice
1 tsp grenadine
6 drops Maraschino liqueur
"Sinful Pleasures and Vicious Courses" or Those Munro Girls...
According to Robert Gross, author of The Minutemen and Their World, on the eve of the American Revolution one out of three first born children were conceived out of wedlock. In the 1740's, nineteen percent of all first births were prenuptial conceptions. From the 1740's onward, births less than nine months after marriage steadily increased. By 1774, forty-one percent of all first born children were conceived out of wedlock.
Lexington youth were no exception to this growing trend and according to period accounts, their promiscuous behavior drew the attention of the Reverend Jonas Clarke. The influential minister was so alarmed by the immoral conduct that he preached a sermon directed towards the town's youth. Entitled A Sermon Preached in the Evening to the Youth, Clarke warned against the "sinful Pleasures and vicious Courses to which there are so many and such strong and alluring Temptation in this Part of Life. . . young People . . . were surrounded by the alluring Snares, Wiles, and Temptations."
Clarke urged his young audience not to be "tempted and allured away from God and their Deity to Sinful Pleasure and vicious Courses to their Shame and Sorrow, and finally to their Destruction" and encouraged them to "choose other courses."
Of course, Clarke's sermon must have fallen on deaf ears as the promiscuous behavior of several young adults from Lexington eventually played out in the Middlesex County Court. All of these hearings addressed the birth of "bastard" children born outside of wedlock.
In the 18th Century the birth of illegitimate children were treated as criminal in nature and punished by the imposition of a fine.
For example, "Sarah Mead of Lexington in the County of Middlesex, spinster, being presented for the crime of fornication on file comes into the court and pleads guilty and says she was delivered of a bastard female child born of her body in Lexington aforesaid on the 13th day of January last, which child is still living, and she charges Thomas Nunning of Bedford in the same County, husbandman, with being the father of said child... Sept. 8, 1772."
Likewise, "Lydia Simends of Lexington in the County of Middlesex, spinster, comes into court and confesses she has been guilty of the crime of fornication at said Woburn... whereof she there afterward had a bastard male child born of her body on the 15th day of September last which child is still living. The court having considered her offense ordered that the said Lydia five shillings to be disposed of as the law directs and that she pay fees and costs, standing committed til performed. March 8, 1774."
Curiously, it appears that four girls from two Lexington Munro families appeared before the Court on five occasions. Rachel Munro, daughter of Marrett Munro, was fined for "fornication and says she was delivered of a bastard child at Lexington on the first day of December last (which child still living) and she charges Thomas Godding ofLexington, cordwainer, with being the father of said child.... Date March 12, 1765." Four years later she was back before the Court again. "Rachel Munro, spinster, presented for the crime of fornication, resulted in birth of bastard girl on Nov. 30, 1769. Pleads guilty and charges Benjamin Bodge of Charlestown as father. Case dated April 2, 1770."
Rachel's younger sister Bethia also appeared before the Court in 1775. "Bethia Munro of Lexington in the County of Middlesex, single woman, comes into the court and confesses she has been guilty of the crime of fornication in said Lexington whereof she there afterwards had a bastard male child born of her body on the 24th day of February 1775 which child is still living and she charges Samuel Bowman of said Lexington with being the father of said child. The Court orders that Bethia Munro pay a fine of six shillings to be disposed of as the law directs and that she pay fees and costs, standing committed til performed."
Two of Thomas Munro's daughters were also hauled before the Court. "Sarah Munro [of Lexington], spinster, presented for the crime of fornication, resulted in birth of bastard girl on Dec. 20, 1767. Pleads guilty and charges Wm. Swaney of Charlestown."
Finally, "Abigail Munro, crime of fornication resulted in the birth of bastard girl on Oct. 27, 1769. Pleads guilty and charges Jonathan Peirce of Lexington. Case dated Nov. 27, 1770."
Posted by Alexander R. Cain at 10:08 PM 3 comments:
"A Schooner of Forty-Five Tons . . . Intended for the Enemy in Boston" - Interdiction of British Supplies by Massachusetts Privateers
In our last post, we discussed efforts by the Massachusetts Committee of Safety to prevent provisions from reaching the British Army trapped in Boston. Today we'll examine accounts detailing the activities of Massachusetts privateers.
It appears that by early fall of 1775, privateers from Newburyport, Beverly, Salem and Plymouth were actively cruising the waters off of Massachusetts Bay in search of supply ships destined for Boston. Many of these privateers traveled in "wolf packs" that varied in size from a few ships to over twenty. One such wolf pack from Newburyport consisted of twenty-five vessels and over 2800 men. A second Newburyport armada boasted thirty vessels.
According to reports from the Essex Gazette, Massachusetts privateers were far more successful in cutting off supplies than their land based counterparts. As early as September 9, 1775, the newspaper reported that "Last Saturday a privateer belonging to Newburyport carried into Portsmouth a schooner of forty-five tons, loaded with potatoes and turnips intended for the enemy in Boston."
Two months later, the Lee, a privateer under the command of one Captain Manly, captured the British vessel Nancy. According to a December 7, 1775 description, "Captain Manly, in the Lee, a vessel of war, in the service of the United Colonies, carried into Cape Ann a large brig called the Nancy which he took off that place, bound from London to Boston, laden with about three hundred and fifty caldrons of coal; and a quantity of bale goods, taken by Captain Manly, was carried into Salem. She is about two hundred tons burthen, and is almost a new ship."
Of course, the Nancy was a military ordinance supply ship from Woolwich, England and also contained several brass cannons and a large quantity of arms and ammunition.
Interestingly, that same account hints that Massachusetts privateers were becoming problematic for the British. "Several vessels loaded with fuel, provisions of various kinds, &c, bound to Boston, have been carried into Salem and Beverly within a few days past."
A few weeks after the capture of the Nancy, the Essex Gazette announced Captain Manly had struck again. "Captain Manly has, within a few days past, taken another valuable prize, a sloop from Virginia bound for Boston, loaded with corn and oats; fitted out and sent by Lord Dunniore."
On Christmas Day, a Plymouth based privateer successfully intercepted a supply sloop from New York. "On the 25th of December last [1775] was taken by a Plymouth privateer and carried in there a small sloop from New York, Moses Wyman, Master, laden with provisions fur the ministerial army in Boston, consisting of thirty-five fresh hogs, one hundred barrels of pork, fifty barrels fine New York pippins, twenty firkins hog's feet, some quarters of beef, turkeys, &c., &c."
Less than six months after Massachusetts privateer operations commenced, eight captured vessels had already been brought into Newburyport. One period account from March 6, 1776 describes the fifth vessel captured. "A few days since, the Yankee Hero sent into Newburyport another prize, a fine brig of about two hundred tons burthen, laden with coal, cheese, &c, bound for White Haven, for the use of the ministerial butchers, under the command of General Howe, Governor of Boston. This is the fifth prize out of eight which sailed states from the above port, and we are in hopes of giving a good account of the three remaining."
Even as the British army was preparing to evacuate Boston, the famed Captain Manly was still harassing Crown shipping lanes. On March 14, 1776 "a transport brig of sixteen guns, laden with naval stores and provisions bound from Boston for the ministerial fleet at the southward was taken. A ship of two hundred and forty tons also captured by Captain Manly about this time was shipped with six double fortified four-pounders, two swivels, and three barrels of powder, while the cargo consisted of one hundred and seventy-five butts of porter, twelve packages of medicine with largo quantities of coal, sourkrout, &c, besides a great number of packages for the officers in Boston. She also brought out sixty live hogs, but only one of them was alive when she was carried in."
Privateering proved to be quite profitable for Massachusetts coastal towns. At the height of the war, almost one hundred privateer vessels hailed from Newburyport alone. According to historian George Clark, over a period of four months (November 1775 to March 1776) the number of British vessels captured en route to Boston "amounted to thirty-one, their tonnage to 3,045 tons."
Posted by Alexander R. Cain at 1:49 PM 1 comment:
"For the Prevention of Any Provisions Being Carried Into the Town of Boston" - Early War Efforts to Cut Off Supplies From Boston
Following the Battles of Lexington and Concord, the Massachusetts Grand Army surrounded Boston and began to lay siege to it. The Massachusetts Committee of Safety quickly recognized that in order to drive the British army from Boston, it had to starve them out.
On May 7, 1775, the Committee passed a resolution ordering selectmen and Committee of Correspondence members for Chelsea "to take effectual methods for the prevention of any Provisions being carried into the Town of Boston."
Unfortunately, the resolution proved to be difficult for the town as Chelsea selectmen lacked the authority to order the Massachusetts Army to mobilize. Likewise, some residents believed the execution of the order would have a negative impact on their livelihoods. William Harris, a manager at Oliver Wendell's farm on Hog's Island, later confided that he was "very uneasy, the people from the Men of War frequently go to the Island to Buy fresh Provision, his own safety obliges him to sell to them, on the other Hand the Committee of Safety have threatened if he sells anything to the Army or Navy, that they will take all the Cattle from the Island, & our folks tell him they shall handle him rufly."
The Committee of Safety recognized Chelsea could not go it alone and revisited the issue on May 14, 1775. After some debate, it was decided that the best way to prevent provisions from falling into enemy hands was to remove them altogether. Hence, the committee instructed "that all the live-stock be taken from Noddle's Island, Hog Island, and Snake Island, and from that part of Chelsea near the seacoast, and be driven back." In turn, the Committee ordered "Committee of Correspondence and Selectmen of the Towns of Medford, Malden, Chelsea, and Lynn, and that they be supplied with such men as they shall need, from the Regiment now at Medford."
The "regiment now at Medford" was the 1st New Hampshire Regiment under the command of John Stark. Unfortunately, Stark reported that his unit could not carry out the mission because it was too poorly equipped. After receiving this news, the Committee of Safety resumed debate on how to best undertake interdiction operations.
Meanwhile the British army began to dispatch forage parties to Grape Island.
Provincial leaders scrambled to find a way to prevent further such raids and stop the flow of supplies into Boston. The Committee of Safety drafted a new resolution to the Massachusetts Provincial Congress on May 23, 1775. The Committee urged the Provincial Congress to use its authority to secure resources on the harbor islands and Massachusetts seacoast. The next day, the Committee issued a second resolution, stating "Resolved, That it be recommended to Congress immediately to take such order respecting the removal of the Sheep and Hay from Noddle's Island, as they may judge proper, together with the stock on adjacent islands."
In compliance with the Committee of Safety resolutions, Major General Artemas Ward, commander-in-chief of the army surrounding Boston, convened a council of war to discuss removing or destroying all supplies on Noddle's and Hog Islands. From this meeting a plan would be formulated regarding the removal of resources from some of the nearby Boston Harbor islands. Unfortunately, the end result of the plan would be the Battle of Chelsea Creek.
"With a Company-Wide Space Between the Two" - Two ...
Shrub, Rattle Skull and Fish House Punch! (Oh My!)...
"Sinful Pleasures and Vicious Courses" or Those Mu...
"A Schooner of Forty-Five Tons . . . Intended for ...
"For the Prevention of Any Provisions Being Carrie...


text:
Twitter FacebookInstagram | TSB
Nominate now for 2020
Child of Courage
Cameron Weir
When his parents' car spun off the road and plunged into a canal, Cameron Weir did not hesitate to save the lives of his younger brother and sister who were trapped in the wreck.
Disaster struck the family from Cheshire when their 4x4 skidded on diesel as they were returning home one lunchtime. The car clipped a metal barrier and rolled down a hill, landing upside-down in the water.
Cameron, who was only 12 at the time, undid his seatbelt and swam over the headrests and through a smashed window to the surface where he discovered he was the first to escape.
Taking a deep breath, the brave youngster risked his own life to return to the car and rescue his seven-year-old brother Mac and 10-year-old sister Rosie, who has severe mental and physical disabilities, and requires round-the-clock care.
"I went into autopilot and knew I had to get them out," says Cameron. "I was scared, but it was all happening too fast and I didn't really think about what I was doing."
Once Mac was free, Cameron's mum Beryl swam him to the bank while Cameron returned for Rosie whom he knew couldn't swim.
The cold water was cloudy and Rosie was fully submerged, so Cameron had to feel for her seatbelt. He managed to undo it but had to return to the car for a third time to pull her out.
Rosie had briefly fallen unconscious but the little girl thinks she fell asleep and woke up when her heroic brother saved her.
"When I got to the bank and looked back," says mum Beryl, "I thought Cameron and Rosie had gone. Then he came up out of the water like a dolphin and as he twisted over on his back I could see he had Rosie on his chest and I was shouting across the canal, 'I'm so proud of you!'"
Meanwhile, passers-by pulled Cameron's unconscious father, Angus, to safety.
On the canal bank, Cameron took charge of his family and tried to keep his mum awake after she passed out.
In fact, he dealt with the situation with such aplomb that firefighters mistook him for a passer-by instead of a survivor.
The children were taken to hospital, but thanks to Cameron's quick actions were not seriously hurt.
"I think he's wonderful," says Beryl. "I know I would have lost the others if Cameron hadn't been in the car with us."
Unfortunately, the accident left Angus with health problems and he often needs a wheelchair to get around, but Cameron has shown extraordinary strength in caring for the family.
"His actions would have been heroic from anybody," admits Beryl, "but from a child it's quite unbelievable."
2005 | History
The 7th Pride of Britain Awards were televised on ITV November 11th, 2005.
Outstanding Bravery
Tony Baker | Julia O'Connor
Hope Farrelly | Cameron Weir | Shae Thomas| Ashleigh Huxley
Neighbour of the Year
Lesley Pulman
Prince's Trust Young Achiever
Carer of the Year
Asmeret Tesfazghi
Liz Owens
Outstanding Achievement
The 2012 Olympics Bid Team
Beyond the call of duty
Emergency services, Transport & NHS staff - London bomings
The McCartney Sisters | Jane Tomlinson | Liz Carnell
Inspirational Sportsmen
The England Cricket Team
Outstanding Contribution
Richard Carr-Gomm
The Mirror's Pride of Britain Awards in partnership with TSB celebrate the achievements of truly remarkable people who make our world a better place.
Pride of Britain
One Canada Square
Enquiries: This email address is being protected from spambots. You need JavaScript enabled to view it.
Follow us @PrideOfBritain
Tweets by @PrideOfBritain
Privacy Notice | Cookie Notice
Copyright © 2020 Pride of Britain
Do you know someone who deserves a Pride of Britain award?


The purpose of the DigiBio App is to provide information to the users regarding their exercise activity and motivate them to be active in their daily lives. The App may also connect to any of the user's wearable devices and with their permission, pulls the data from the wearable devices into this App for storage on our servers. The App also allows the users to form one or more social circles and to motivate individuals in each social circle to achieve their self-care goals. In addition, the App allows each user or a social circle to set up their own goals, pledges, and challenges and to pick various events. The App allows users to log their exercises, nutrition and health data. Users may also generate their own workout of the day using the App's proprietary algorithm based on the user's input. The user can also follow a social circle to see the circle members' progress toward their own self-care. By using this App, users in a social circle can send messages to each other to provide motivation. The main goal of the App is to motivate users to obtain their self-care goals. By using the social circle feature in the App, you acknowledge and agree that certain information about you will be shared within the social circle and is accessible by other users within the social circle.
•	data from all users will be aggregated so that each persons' data can be compared to all other users' data (without revealing identifying information for any user) thereby providing a point of reference for the personal and health information of each user.
The App may collect and store additional information at the time of registration, but users will have the option not to provide such additional information.
•	Passive data like temperature, weather pattern, geo location etc.
•	From you: We collect information as mentioned for registration as well as information necessary to use the App, when you voluntarily provide such information to us.
•	Through your device: Certain information is collected automatically through your device, such as your operating system name and version, device manufacturer and model, device identifier, language, and the name and version of the App you are using. We use this information to ensure that the App functions properly and to understand usage of the App.
•	Through server log files: Your "IP Address" is a number that is automatically assigned to the device that you are using by your Internet Service Provider (ISP). An IP Address is identified and logged automatically in our server log files whenever a user uses the App, along with the time of the use and the pages visited within the App. Collecting IP Addresses is standard practice on the Internet and is done automatically by many websites. We use IP Addresses for purposes such as helping to calculate App usage levels, diagnose server problems and administer the App.
•	Physical Location: We may collect the physical location of your device, for example, using satellite, cell phone tower or Wi-Fi signals. We may use your device's physical location to provide you with personalized location-based services and content (for example, information regarding local healthcare providers). We may also aggregate this information to display usage trends. For example, we may aggregate search results and trends for particular conditions in a particular geographic area and display those aggregate results. We may also share your device's physical location, combined with information about what advertisements you viewed and other information we collect, with our marketing partners to enable them to provide you with more personalized content and to study the effectiveness of advertising campaigns. In some instances, you may be permitted to allow or deny such uses and/or sharing of your device's location, but if you choose to deny such uses and/or sharing, we and/or our marketing partners may not be able to provide you with the applicable personalized services and content.
•	By aggregating and deidentifying information: Aggregated deidentified health information does not personally identify you or any other user of the App. For example, we may aggregate personal information to calculate the percentage of our users who have a particular zip code, and we may aggregate health information to calculate the percentage of our users with particular medical conditions.
•	DigiBio App will store your email and password, but will not share or use this information for any other purpose.
•	We will use the information to provide you with the appropriate reference materials in the App.
•	MavenSphere may use the information for the research, statistical or marketing purposes of itself and its sponsoring employers and health plans. This data may classify users according to personal information entered into the App by the users. However, any aggregated data used by DigiBio App for the purposes listed above will refer to users in terms of anonymous groups defined by broad characteristics (for example, number of men who download the App versus the number of women who download the App, or the average age of individuals who download the App), and will contain no information that would allow individual users, or individual users' information or traits, to be identified.
DigiBio App seeks to use reasonable physical, technical and administrative measures to protect Information under our control, including encrypting data stored by the App. Unfortunately, no data transmission over the Internet or data storage system is guaranteed to be 100% secure. There are some risks of unauthorized interception of the information while traveling over the internet. By using this App, you accept the risk of the potential unauthorized interception of your information by unauthorized individuals.


text:
SD County Supervisors vote to continue COVID emergency declaration
County of San Diego
SAN DIEGO (CNS) — The San Diego County Board of Supervisors voted 3-2 Tuesday to continue the local health emergency order connected to the efforts to combat the COVID-19 pandemic.
Supervisors Nathan Fletcher, Terra Lawson-Remer and Nora Vargas were in favor, while Joel Anderson and Jim Desmond voted no after a regular update on the virus.
In a written statement, Desmond said he voted against continuing the emergency because if the county is "willing to turn people away from working at the County of San Diego, hospitals, doctor's offices, police officers, firefighters, and many other industries, (then) this emergency is over."
Anderson, through a spokesman, declined to comment.
Based on Desmond's suggestions, the board also voted unanimously for a serious of recommendations -- providing monoclonal treatments, expanding testing of all types, including antibody and data collection, and a future presentation on natural immunity.
Desmond said the public doesn't know that monoclonal treatments are available, and the county needs to make a stronger effort to inform them.
Antibody testing would be help people make decisions on their health, Desmond said.
Germany and other nations are researching to see if people are recovering with antibody testing, and the county should follow that lead and also create its own database, Desmond said.
Desmond added that if certain people truly cannot receive a vaccine because of health or religious reasons, showing proof of antibodies might help them be able to keep their jobs.
Dr. Wilma Wooten, county public officer, said that type of test "is at one point in time" and doesn't indicate what person may look like in six months.
Wooten added that UC San Diego has researched such testing, but that information may not predict a person's long-term immunity.
Lawson-Remer called for better public outreach on COVID-19 booster vaccines to enable the public to know where and how they can receive them.
Denise Foster, the county's chief nurse, said the county is working with community organizations to understand the barriers that prevent people from being vaccinated. Supervisor Nora Vargas offered her team to help Lawson- Remer's office out on vaccine efforts.
Vargas added that inequities existed before the pandemic and language barriers also created mistrust. However, help from Hispanic organizations improved vaccination rates.
"It's been a tough year for everyone," Vargas said, adding that she hoped 2022 is a healthier year.
During the Tuesday presentation, Wooten said the county is still experiencing increased case rates, with the Delta virus variant being predominant.
Wooten added that while the Omicron variant hasn't been detected in the county, "it's only a matter of time" before it will, and that 18 states have reported cases involving the Omicron variant.
Wooten also said that along with the COVID-19 vaccine, residents should get their flu shot.
Since the county declared a state of emergency on Feb. 14, 2020, there have been 390,381 coronavirus cases and 4,357 deaths in San Diego County.


text:
import time

import datetime
import mock
from factory import SubFactory
from factory.fuzzy import FuzzyDateTime, FuzzyAttribute, FuzzyChoice
from mock import patch, Mock

import factory
import pytz
import factory.django
from factory.django import DjangoModelFactory
from django.apps import apps
from django.core.exceptions import ValidationError
from django.utils import timezone
from django.contrib.contenttypes.models import ContentType
from django.db.utils import IntegrityError
from faker import Factory
from waffle.models import Flag, Sample, Switch

from website.notifications.constants import NOTIFICATION_TYPES
from osf.utils import permissions
from website.archiver import ARCHIVER_SUCCESS
from website.settings import FAKE_EMAIL_NAME, FAKE_EMAIL_DOMAIN
from framework.auth.core import Auth

from osf import models
from osf.models.sanctions import Sanction
from osf.models.storage import PROVIDER_ASSET_NAME_CHOICES
from osf.utils.names import impute_names_model
from osf.utils.workflows import (
    DefaultStates,
    DefaultTriggers,
    ApprovalStates,
    SchemaResponseTriggers
)
from addons.osfstorage.models import OsfStorageFile, Region
fake = Factory.create()

# If tests are run on really old processors without high precision this might fail. Unlikely to occur.
fake_email = lambda: '{}+{}@{}'.format(FAKE_EMAIL_NAME, int(time.clock() * 1000000), FAKE_EMAIL_DOMAIN)

# Do this out of a cls context to avoid setting "t" as a local
PROVIDER_ASSET_NAME_CHOICES = tuple([t[0] for t in PROVIDER_ASSET_NAME_CHOICES])

def get_default_metaschema():
    """This needs to be a method so it gets called after the test database is set up"""
    return models.RegistrationSchema.objects.first()

def FakeList(provider, n, *args, **kwargs):
    func = getattr(fake, provider)
    return [func(*args, **kwargs) for _ in range(n)]

class UserFactory(DjangoModelFactory):
    # TODO: Change this to only generate long names and see what breaks
    fullname = factory.Sequence(lambda n: 'Freddie Mercury{0}'.format(n))

    username = factory.LazyFunction(fake_email)
    password = factory.PostGenerationMethodCall('set_password',
                                                'queenfan86')
    is_registered = True
    date_confirmed = factory.Faker('date_time_this_decade', tzinfo=pytz.utc)
    merged_by = None
    verification_key = None

    class Meta:
        model = models.OSFUser

    @classmethod
    def _build(cls, target_class, *args, **kwargs):
        emails = kwargs.pop('emails', [])
        instance = super(DjangoModelFactory, cls)._build(target_class, *args, **kwargs)
        if emails:
            # Save for M2M population
            instance.set_unusable_password()
            instance.save()
        for email in emails:
            instance.emails.create(address=email)
        return instance

    @classmethod
    def _create(cls, target_class, *args, **kwargs):
        emails = kwargs.pop('emails', [])
        instance = super(DjangoModelFactory, cls)._create(target_class, *args, **kwargs)
        if emails and not instance.pk:
            # Save for M2M population
            instance.set_unusable_password()
            instance.save()
        for email in emails:
            instance.emails.create(address=email)
        return instance

    @factory.post_generation
    def set_names(self, create, extracted):
        parsed = impute_names_model(self.fullname)
        for key, value in parsed.items():
            setattr(self, key, value)

    @factory.post_generation
    def set_emails(self, create, extracted):
        if not self.emails.filter(address=self.username).exists():
            if not self.id:
                if create:
                    # Perform implicit save to populate M2M
                    self.save(clean=False)
                else:
                    # This might lead to strange behavior
                    return
            self.emails.create(address=str(self.username).lower())

class AuthUserFactory(UserFactory):
    """A user that automatically has an api key, for quick authentication.

    Example: ::
        user = AuthUserFactory()
        res = self.app.get(url, auth=user.auth)  # user is "logged in"
    """

    @factory.post_generation
    def add_auth(self, create, extracted):
        self.auth = (self.username, 'queenfan86')

class AuthFactory(factory.base.Factory):
    class Meta:
        model = Auth
    user = factory.SubFactory(UserFactory)

class UnregUserFactory(DjangoModelFactory):
    email = factory.LazyFunction(fake_email)
    fullname = factory.Sequence(lambda n: 'Freddie Mercury{0}'.format(n))
    date_registered = factory.Faker('date_time', tzinfo=pytz.utc)

    class Meta:
        model = models.OSFUser

    @classmethod
    def _build(cls, target_class, *args, **kwargs):
        """Build an object without saving it."""
        ret = target_class.create_unregistered(email=kwargs.pop('email'), fullname=kwargs.pop('fullname'))
        for key, val in kwargs.items():
            setattr(ret, key, val)
        return ret

    @classmethod
    def _create(cls, target_class, *args, **kwargs):
        ret = target_class.create_unregistered(email=kwargs.pop('email'), fullname=kwargs.pop('fullname'))
        for key, val in kwargs.items():
            setattr(ret, key, val)
        ret.save()
        return ret

class UnconfirmedUserFactory(DjangoModelFactory):
    """Factory for a user that has not yet confirmed their primary email
    address (username).
    """
    class Meta:
        model = models.OSFUser
    username = factory.LazyFunction(fake_email)
    fullname = factory.Sequence(lambda n: 'Freddie Mercury{0}'.format(n))
    password = 'lolomglgt'

    @classmethod
    def _build(cls, target_class, username, password, fullname):
        """Build an object without saving it."""
        instance = target_class.create_unconfirmed(
            username=username, password=password, fullname=fullname
        )
        instance.date_registered = fake.date_time(tzinfo=pytz.utc)
        return instance

    @classmethod
    def _create(cls, target_class, username, password, fullname):
        instance = target_class.create_unconfirmed(
            username=username, password=password, fullname=fullname
        )
        instance.date_registered = fake.date_time(tzinfo=pytz.utc)

        instance.save()
        return instance

class BaseNodeFactory(DjangoModelFactory):
    title = factory.Faker('catch_phrase')
    description = factory.Faker('sentence')
    created = factory.LazyFunction(timezone.now)
    creator = factory.SubFactory(AuthUserFactory)

    class Meta:
        model = models.Node

    #Fix for adding the deleted date.
    @classmethod
    def _create(cls, *args, **kwargs):
        if kwargs.get('is_deleted', None):
            kwargs['deleted'] = timezone.now()
        return super(BaseNodeFactory, cls)._create(*args, **kwargs)

class ProjectFactory(BaseNodeFactory):
    category = 'project'

class DraftNodeFactory(BaseNodeFactory):
    category = 'project'

    class Meta:
        model = models.DraftNode

class ProjectWithAddonFactory(ProjectFactory):
    """Factory for a project that has an addon. The addon will be added to
    both the Node and the creator records. ::

        p = ProjectWithAddonFactory(addon='github')
        p.get_addon('github') # => github node settings object
        p.creator.get_addon('github') # => github user settings object

    """

    # TODO: Should use mock addon objects
    @classmethod
    def _build(cls, target_class, addon='s3', *args, **kwargs):
        """Build an object without saving it."""
        instance = ProjectFactory._build(target_class, *args, **kwargs)
        auth = Auth(user=instance.creator)
        instance.add_addon(addon, auth)
        instance.creator.add_addon(addon)
        return instance

    @classmethod
    def _create(cls, target_class, addon='s3', *args, **kwargs):
        instance = ProjectFactory._create(target_class, *args, **kwargs)
        auth = Auth(user=instance.creator)
        instance.add_addon(addon, auth)
        instance.creator.add_addon(addon)
        instance.save()
        return instance

class NodeFactory(BaseNodeFactory):
    category = 'hypothesis'
    parent = factory.SubFactory(ProjectFactory)

class InstitutionFactory(DjangoModelFactory):
    name = factory.Faker('company')
    login_url = factory.Faker('url')
    logout_url = factory.Faker('url')
    domains = FakeList('url', n=3)
    email_domains = FakeList('domain_name', n=1)
    logo_name = factory.Faker('file_name')

    class Meta:
        model = models.Institution

class NodeLicenseRecordFactory(DjangoModelFactory):
    year = factory.Faker('year')
    copyright_holders = FakeList('name', n=3)

    class Meta:
        model = models.NodeLicenseRecord

    @classmethod
    def _create(cls, *args, **kwargs):
        kwargs['node_license'] = kwargs.get(
            'node_license',
            models.NodeLicense.objects.get(name='No license')
        )
        return super(NodeLicenseRecordFactory, cls)._create(*args, **kwargs)

class NodeLogFactory(DjangoModelFactory):
    class Meta:
        model = models.NodeLog
    action = 'file_added'
    params = {'path': '/'}
    user = SubFactory(UserFactory)

class PrivateLinkFactory(DjangoModelFactory):
    class Meta:
        model = models.PrivateLink

    name = factory.Sequence(lambda n: 'Example Private Link #{}'.format(n))
    key = factory.Faker('md5')
    anonymous = False
    creator = factory.SubFactory(UserFactory)

    @classmethod
    def _create(cls, target_class, *args, **kwargs):
        instance = super(PrivateLinkFactory, cls)._create(target_class, *args, **kwargs)
        if instance.is_deleted and not instance.deleted:
            instance.deleted = timezone.now()
            instance.save()
        return instance

class CollectionFactory(DjangoModelFactory):
    class Meta:
        model = models.Collection

    is_bookmark_collection = False
    title = factory.Faker('catch_phrase')
    creator = factory.SubFactory(UserFactory)

    @classmethod
    def _create(cls, *args, **kwargs):
        collected_types = kwargs.pop('collected_types', ContentType.objects.filter(app_label='osf', model__in=['abstractnode', 'basefilenode', 'collection', 'preprint']))
        obj = cls._build(*args, **kwargs)
        obj.save()
        # M2M, requires initial save
        obj.collected_types.add(*collected_types)
        return obj

class BookmarkCollectionFactory(CollectionFactory):
    is_bookmark_collection = True

class CollectionProviderFactory(DjangoModelFactory):
    name = factory.Faker('company')
    description = factory.Faker('bs')
    external_url = factory.Faker('url')

    class Meta:
        model = models.CollectionProvider

    @classmethod
    def _create(cls, *args, **kwargs):
        user = kwargs.pop('creator', None)
        obj = cls._build(*args, **kwargs)
        obj._creator = user or UserFactory()  # Generates primary_collection
        obj.save()
        return obj

class RegistrationProviderFactory(DjangoModelFactory):
    name = factory.Faker('company')
    description = factory.Faker('bs')
    external_url = factory.Faker('url')
    access_token = factory.Faker('bs')
    share_source = factory.Sequence(lambda n: 'share source #{0}'.format(n))

    class Meta:
        model = models.RegistrationProvider

    @classmethod
    def _create(cls, *args, **kwargs):
        user = kwargs.pop('creator', None)
        _id = kwargs.pop('_id', None)
        try:
            obj = cls._build(*args, **kwargs)
        except IntegrityError as e:
            # This is to ensure legacy tests don't fail when their _ids aren't unique
            if _id == models.RegistrationProvider.default__id:
                pass
            else:
                raise e
        if _id and _id != 'osf':
            obj._id = _id

        obj._creator = user or models.OSFUser.objects.first() or UserFactory()  # Generates primary_collection
        obj.save()
        return obj

class OSFGroupFactory(DjangoModelFactory):
    name = factory.Faker('company')
    created = factory.LazyFunction(timezone.now)
    creator = factory.SubFactory(AuthUserFactory)

    class Meta:
        model = models.OSFGroup

class RegistrationFactory(BaseNodeFactory):

    creator = None
    # Default project is created if not provided
    category = 'project'

    @classmethod
    def _build(cls, target_class, *args, **kwargs):
        raise Exception('Cannot build registration without saving.')

    @classmethod
    def _create(cls, target_class, project=None, is_public=False,
                schema=None, draft_registration=None,
                archive=False, embargo=None, registration_approval=None, retraction=None,
                provider=None,
                *args, **kwargs):
        user = None
        if project:
            user = project.creator
        user = kwargs.pop('user', None) or kwargs.get('creator') or user or AuthUserFactory()
        kwargs['creator'] = user
        provider = provider or models.RegistrationProvider.get_default()
        # Original project to be registered
        project = project or target_class(*args, **kwargs)
        if project.is_admin_contributor(user):
            project.add_contributor(
                contributor=user,
                permissions=permissions.CREATOR_PERMISSIONS,
                log=False,
                save=False
            )
        project.save()

        if draft_registration:
            schema = draft_registration.registration_schema
        else:
            schema = schema or get_default_metaschema()

        # Default registration parameters
        parent_registration = kwargs.get('parent')
        if parent_registration:
            schema = parent_registration.registration_schema
            draft_registration = parent_registration.draft_registration.get()

        if not draft_registration:
            draft_registration = DraftRegistrationFactory(
                branched_from=project,
                initator=user,
                registration_schema=schema,
                provider=provider,
            )
        auth = Auth(user=user)
        register = lambda: project.register_node(
            schema=schema,
            auth=auth,
            draft_registration=draft_registration,
            provider=provider,
            parent=parent_registration
        )

        def add_approval_step(reg):
            if embargo:
                reg.embargo = embargo
            elif registration_approval:
                reg.registration_approval = registration_approval
            elif retraction:
                reg.retraction = retraction
            else:
                reg.require_approval(reg.creator)
            reg.save()
            reg.sanction.add_authorizer(reg.creator, reg)
            reg.sanction.save()

        with patch('framework.celery_tasks.handlers.enqueue_task'):
            reg = register()
            add_approval_step(reg)
        if not archive:
            with patch.object(reg.archive_job, 'archive_tree_finished', Mock(return_value=True)):
                archive_job = reg.archive_job
                archive_job.status = ARCHIVER_SUCCESS
                archive_job.done = True
                archive_job.save()
                reg.sanction.state = Sanction.APPROVED
                reg.sanction.save()
        if is_public:
            reg.is_public = True
        reg.files_count = reg.registered_from.files.filter(deleted_on__isnull=True).count()
        draft_registration.registered_node = reg
        draft_registration.save()
        reg.save()
        return reg

class WithdrawnRegistrationFactory(BaseNodeFactory):

    @classmethod
    def _create(cls, *args, **kwargs):

        registration = kwargs.pop('registration', RegistrationFactory())
        registration.is_public = True
        user = kwargs.pop('user', registration.creator)

        registration.retract_registration(user)
        withdrawal = registration.retraction
        token = list(withdrawal.approval_state.values())[0]['approval_token']
        with patch('osf.models.AbstractNode.update_search'):
            withdrawal.approve_retraction(user, token)
        withdrawal.save()

        return withdrawal

class SanctionFactory(DjangoModelFactory):
    class Meta:
        abstract = True

    @classmethod
    def _create(cls, target_class, initiated_by=None, approve=False, *args, **kwargs):
        user = kwargs.pop('user', None) or UserFactory()
        kwargs['initiated_by'] = initiated_by or user
        sanction = super()._create(target_class, *args, **kwargs)
        reg_kwargs = {
            'creator': user,
            'user': user,
            sanction.SHORT_NAME: sanction
        }
        RegistrationFactory(**reg_kwargs)
        if not approve:
            sanction.state = Sanction.UNAPPROVED
            sanction.save()
        return sanction

class RetractionFactory(SanctionFactory):
    class Meta:
        model = models.Retraction
    user = factory.SubFactory(UserFactory)

class EmbargoFactory(SanctionFactory):
    class Meta:
        model = models.Embargo
    user = factory.SubFactory(UserFactory)

class RegistrationApprovalFactory(SanctionFactory):
    class Meta:
        model = models.RegistrationApproval
    user = factory.SubFactory(UserFactory)

class EmbargoTerminationApprovalFactory(DjangoModelFactory):

    @classmethod
    def create(cls, registration=None, user=None, embargo=None, *args, **kwargs):
        if registration:
            if not user:
                user = registration.creator
        else:
            user = user or UserFactory()
            if not embargo:
                embargo = EmbargoFactory(state=models.Sanction.APPROVED, approve=True)
                registration = embargo._get_registration()
            else:
                registration = RegistrationFactory(creator=user, user=user, embargo=embargo)
        with mock.patch('osf.models.sanctions.EmailApprovableSanction.ask', mock.Mock()):
            approval = registration.request_embargo_termination(user)
            return approval

class DraftRegistrationFactory(DjangoModelFactory):
    class Meta:
        model = models.DraftRegistration

    @classmethod
    def _create(cls, *args, **kwargs):
        title = kwargs.pop('title', None)
        initiator = kwargs.get('initiator', None)
        description = kwargs.pop('description', None)
        branched_from = kwargs.get('branched_from', None)
        registration_schema = kwargs.get('registration_schema')
        registration_metadata = kwargs.get('registration_metadata')
        provider = kwargs.get('provider')
        branched_from_creator = branched_from.creator if branched_from else None
        initiator = initiator or branched_from_creator or kwargs.get('user', None) or kwargs.get('creator', None) or UserFactory()
        registration_schema = registration_schema or get_default_metaschema()
        registration_metadata = registration_metadata or {}
        provider = provider or models.RegistrationProvider.get_default()
        provider.schemas.add(registration_schema)
        draft = models.DraftRegistration.create_from_node(
            node=branched_from,
            user=initiator,
            schema=registration_schema,
            data=registration_metadata,
            provider=provider,
        )
        if title:
            draft.title = title
        if description:
            draft.description = description
        draft.registration_responses = draft.flatten_registration_metadata()
        draft.save()
        return draft

class CommentFactory(DjangoModelFactory):
    class Meta:
        model = models.Comment

    content = factory.Sequence(lambda n: 'Comment {0}'.format(n))

    @classmethod
    def _build(cls, target_class, *args, **kwargs):
        node = kwargs.pop('node', None) or NodeFactory()
        user = kwargs.pop('user', None) or node.creator
        target = kwargs.pop('target', None) or models.Guid.load(node._id)
        content = kwargs.pop('content', None) or 'Test comment.'
        instance = target_class(
            node=node,
            user=user,
            target=target,
            content=content,
            *args, **kwargs
        )
        if isinstance(target.referent, target_class):
            instance.root_target = target.referent.root_target
        else:
            instance.root_target = target
        return instance

    @classmethod
    def _create(cls, target_class, *args, **kwargs):
        node = kwargs.pop('node', None) or NodeFactory()
        user = kwargs.pop('user', None) or node.creator
        target = kwargs.pop('target', None) or models.Guid.load(node._id)
        content = kwargs.pop('content', None) or 'Test comment.'
        instance = target_class(
            node=node,
            user=user,
            target=target,
            content=content,
            *args, **kwargs
        )
        if isinstance(target.referent, target_class):
            instance.root_target = target.referent.root_target
        else:
            instance.root_target = target
        instance.save()
        return instance

class SubjectFactory(DjangoModelFactory):
    text = factory.Sequence(lambda n: 'Example Subject #{}'.format(n))

    class Meta:
        model = models.Subject

    @classmethod
    def _create(cls, target_class, parent=None, provider=None, bepress_subject=None, *args, **kwargs):
        provider = provider or models.PreprintProvider.objects.first() or PreprintProviderFactory(_id='osf')
        if provider._id != 'osf' and not bepress_subject:
            osf = models.PreprintProvider.load('osf') or PreprintProviderFactory(_id='osf')
            bepress_subject = SubjectFactory(provider=osf)
        try:
            ret = super()._create(target_class, parent=parent, provider=provider, bepress_subject=bepress_subject, *args, **kwargs)
        except (IntegrityError, ValidationError):
            ret = models.Subject.objects.get(text=kwargs['text'])
            if parent:
                ret.parent = parent
        return ret

class PreprintProviderFactory(DjangoModelFactory):
    _id = factory.Sequence(lambda n: f'slug{n}')

    name = factory.Faker('company')
    description = factory.Faker('bs')
    external_url = factory.Faker('url')
    share_source = factory.Sequence(lambda n: 'share source #{0}'.format(n))

    class Meta:
        model = models.PreprintProvider

    @classmethod
    def _build(cls, target_class, *args, **kwargs):
        try:
            instance = models.PreprintProvider.objects.get(_id=kwargs['_id'])
        except models.PreprintProvider.DoesNotExist:
            instance = super()._build(target_class, *args, **kwargs)

        if not instance.share_title:
            instance.share_title = instance._id
        return instance

    @classmethod
    def _create(cls, target_class, *args, **kwargs):
        try:
            instance = models.PreprintProvider.objects.get(_id=kwargs['_id'])
        except models.PreprintProvider.DoesNotExist:
            instance = super()._create(target_class, *args, **kwargs)

        if not instance.share_title:
            instance.share_title = instance._id
            instance.save()
        return instance

def sync_set_identifiers(preprint):
    from website import settings
    doi = settings.DOI_FORMAT.format(prefix=preprint.provider.doi_prefix, guid=preprint._id)
    preprint.set_identifier_values(doi=doi)

class PreprintFactory(DjangoModelFactory):
    class Meta:
        model = models.Preprint

    title = factory.Faker('catch_phrase')
    description = factory.Faker('sentence')
    created = factory.LazyFunction(timezone.now)
    creator = factory.SubFactory(AuthUserFactory)

    doi = factory.Sequence(lambda n: '10.123/{}'.format(n))
    provider = factory.SubFactory(PreprintProviderFactory)

    @classmethod
    def _build(cls, target_class, *args, **kwargs):
        creator = kwargs.pop('creator', None) or UserFactory()
        provider = kwargs.pop('provider', None) or PreprintProviderFactory()
        project = kwargs.pop('project', None) or None
        title = kwargs.pop('title', None) or 'Untitled'
        description = kwargs.pop('description', None) or 'None'
        is_public = kwargs.pop('is_public', True)
        instance = target_class(provider=provider, title=title, description=description, creator=creator, node=project, is_public=is_public)
        return instance

    @classmethod
    def _create(cls, target_class, *args, **kwargs):
        update_task_patcher = mock.patch('website.preprints.tasks.on_preprint_updated.si')
        update_task_patcher.start()

        finish = kwargs.pop('finish', True)
        set_doi = kwargs.pop('set_doi', True)
        is_published = kwargs.pop('is_published', True)
        instance = cls._build(target_class, *args, **kwargs)
        file_size = kwargs.pop('file_size', 1337)

        doi = kwargs.pop('doi', None)
        license_details = kwargs.pop('license_details', None)
        filename = kwargs.pop('filename', None) or 'preprint_file.txt'
        subjects = kwargs.pop('subjects', None) or [[SubjectFactory()._id]]
        instance.article_doi = doi

        user = kwargs.pop('creator', None) or instance.creator
        instance.save()

        preprint_file = OsfStorageFile.create(
            target_object_id=instance.id,
            target_content_type=ContentType.objects.get_for_model(instance),
            path='/{}'.format(filename),
            name=filename,
            materialized_path='/{}'.format(filename))

        instance.machine_state = kwargs.pop('machine_state', 'initial')
        preprint_file.save()
        from addons.osfstorage import settings as osfstorage_settings

        preprint_file.create_version(user, {
            'object': '06d80e',
            'service': 'cloud',
            osfstorage_settings.WATERBUTLER_RESOURCE: 'osf',
        }, {
            'size': file_size,
            'contentType': 'img/png'
        }).save()
        update_task_patcher.stop()
        if finish:
            auth = Auth(user)

            instance.set_primary_file(preprint_file, auth=auth, save=True)
            instance.set_subjects(subjects, auth=auth)
            if license_details:
                instance.set_preprint_license(license_details, auth=auth)
            instance.set_published(is_published, auth=auth)
            create_task_patcher = mock.patch('website.identifiers.utils.request_identifiers')
            mock_create_identifier = create_task_patcher.start()
            if is_published and set_doi:
                mock_create_identifier.side_effect = sync_set_identifiers(instance)
            create_task_patcher.stop()

        instance.save()
        return instance

class TagFactory(DjangoModelFactory):
    class Meta:
        model = models.Tag

    name = factory.Sequence(lambda n: 'Example Tag #{}'.format(n))
    system = False

class DismissedAlertFactory(DjangoModelFactory):
    class Meta:
        model = models.DismissedAlert

    @classmethod
    def _create(cls, *args, **kwargs):
        kwargs['_id'] = kwargs.get('_id', 'adblock')
        kwargs['user'] = kwargs.get('user', UserFactory())
        kwargs['location'] = kwargs.get('location', 'iver/settings')

        return super(DismissedAlertFactory, cls)._create(*args, **kwargs)

class ApiOAuth2ScopeFactory(DjangoModelFactory):
    class Meta:
        model = models.ApiOAuth2Scope

    name = factory.Sequence(lambda n: 'scope{}'.format(n))
    is_public = True
    is_active = True
    description = factory.Faker('text')

class ApiOAuth2PersonalTokenFactory(DjangoModelFactory):
    class Meta:
        model = models.ApiOAuth2PersonalToken

    owner = factory.SubFactory(UserFactory)
    name = factory.Sequence(lambda n: 'Example OAuth2 Personal Token #{}'.format(n))

    @classmethod
    def _create(cls, *args, **kwargs):
        token = super(ApiOAuth2PersonalTokenFactory, cls)._create(*args, **kwargs)
        token.scopes.add(ApiOAuth2ScopeFactory())
        return token

class ApiOAuth2ApplicationFactory(DjangoModelFactory):
    class Meta:
        model = models.ApiOAuth2Application

    owner = factory.SubFactory(UserFactory)

    name = factory.Sequence(lambda n: 'Example OAuth2 Application #{}'.format(n))

    home_url = 'ftp://ftp.ncbi.nlm.nimh.gov/'
    callback_url = 'http://example.uk'

class ForkFactory(DjangoModelFactory):
    class Meta:
        model = models.Node

    @classmethod
    def _create(cls, *args, **kwargs):

        project = kwargs.pop('project', None)
        user = kwargs.pop('user', project.creator)
        title = kwargs.pop('title', None)

        fork = project.fork_node(auth=Auth(user), title=title)
        fork.save()
        return fork

class IdentifierFactory(DjangoModelFactory):
    class Meta:
        model = models.Identifier

    referent = factory.SubFactory(RegistrationFactory)
    value = factory.Sequence(lambda n: 'carp:/2460{}'.format(n))

    @classmethod
    def _create(cls, *args, **kwargs):
        kwargs['category'] = kwargs.get('category', 'carpid')

        return super(IdentifierFactory, cls)._create(*args, **kwargs)

class NodeRelationFactory(DjangoModelFactory):
    class Meta:
        model = models.NodeRelation

    child = factory.SubFactory(NodeFactory)
    parent = factory.SubFactory(NodeFactory)

class ExternalAccountFactory(DjangoModelFactory):
    class Meta:
        model = models.ExternalAccount
    oauth_key = 'some-silly-key'
    oauth_secret = 'some-super-secret'
    provider = 'mock2'
    provider_id = factory.Sequence(lambda n: 'user-{0}'.format(n))
    provider_name = 'Fake Provider'
    display_name = factory.Sequence(lambda n: 'user-{0}'.format(n))
    profile_url = 'http://wutwut.com/'
    refresh_token = 'some-sillier-key'

class MockOAuth2Provider(models.ExternalProvider):
    name = 'Mock OAuth 2.0 Provider'
    short_name = 'mock2'

    client_id = 'mock2_client_id'
    client_secret = 'mock2_client_secret'

    auth_url_base = 'https://mock2.com/auth'
    callback_url = 'https://mock2.com/callback'
    auto_refresh_url = 'https://mock2.com/callback'
    refresh_time = 300
    expiry_time = 9001

    def handle_callback(self, response):
        return {
            'provider_id': 'mock_provider_id'
        }

class NotificationSubscriptionFactory(DjangoModelFactory):
    class Meta:
        model = models.NotificationSubscription

def make_node_lineage():
    node1 = NodeFactory()
    node2 = NodeFactory(parent=node1)
    node3 = NodeFactory(parent=node2)
    node4 = NodeFactory(parent=node3)

    return [node1._id, node2._id, node3._id, node4._id]

class NotificationDigestFactory(DjangoModelFactory):
    timestamp = FuzzyDateTime(datetime.datetime(1970, 1, 1, tzinfo=pytz.UTC))
    node_lineage = FuzzyAttribute(fuzzer=make_node_lineage)
    user = factory.SubFactory(UserFactory)
    send_type = FuzzyChoice(choices=NOTIFICATION_TYPES.keys())
    message = fake.text(max_nb_chars=2048)
    event = fake.text(max_nb_chars=50)
    class Meta:
        model = models.NotificationDigest

class ConferenceFactory(DjangoModelFactory):
    class Meta:
        model = models.Conference

    endpoint = factory.Sequence(lambda n: 'conference{0}'.format(n))
    name = factory.Faker('catch_phrase')
    active = True
    is_meeting = True

    @factory.post_generation
    def admins(self, create, extracted, **kwargs):
        self.admins.add(*(extracted or [UserFactory()]))

class SessionFactory(DjangoModelFactory):
    class Meta:
        model = models.Session

    @classmethod
    def _build(cls, target_class, *args, **kwargs):
        user = kwargs.pop('user', None)
        instance = target_class(*args, **kwargs)

        if user:
            instance.data['auth_user_username'] = user.username
            instance.data['auth_user_id'] = user._primary_key
            instance.data['auth_user_fullname'] = user.fullname

        return instance

    @classmethod
    def _create(cls, target_class, *args, **kwargs):
        instance = cls._build(target_class, *args, **kwargs)
        instance.save()
        return instance

class ArchiveJobFactory(DjangoModelFactory):
    class Meta:
        model = models.ArchiveJob

class ReviewActionFactory(DjangoModelFactory):
    class Meta:
        model = models.ReviewAction

    trigger = FuzzyChoice(choices=DefaultTriggers.values())
    comment = factory.Faker('text')
    from_state = FuzzyChoice(choices=DefaultStates.values())
    to_state = FuzzyChoice(choices=DefaultStates.values())

    target = factory.SubFactory(PreprintFactory)
    creator = factory.SubFactory(AuthUserFactory)

    is_deleted = False

class ScheduledBannerFactory(DjangoModelFactory):
    # Banners are set for 24 hours from start_date if no end date is given
    class Meta:
        model = models.ScheduledBanner

    name = factory.Faker('name')
    default_alt_text = factory.Faker('text')
    mobile_alt_text = factory.Faker('text')
    default_photo = factory.Faker('file_name')
    mobile_photo = factory.Faker('file_name')
    license = factory.Faker('name')
    color = factory.Faker('color')
    start_date = timezone.now()
    end_date = factory.LazyAttribute(lambda o: o.start_date)

class FlagFactory(DjangoModelFactory):
    name = factory.Faker('catch_phrase')
    everyone = True
    note = 'This is a waffle test flag'

    class Meta:
        model = Flag

class SampleFactory(DjangoModelFactory):
    name = factory.Faker('catch_phrase')
    percent = 100
    note = 'This is a waffle test sample'

    class Meta:
        model = Sample

class SwitchFactory(DjangoModelFactory):
    name = factory.Faker('catch_phrase')
    active = True
    note = 'This is a waffle test switch'

    class Meta:
        model = Switch

class NodeRequestFactory(DjangoModelFactory):
    class Meta:
        model = models.NodeRequest

    creator = factory.SubFactory(AuthUserFactory)
    target = factory.SubFactory(NodeFactory)

    comment = factory.Faker('text')

class PreprintRequestFactory(DjangoModelFactory):
    class Meta:
        model = models.PreprintRequest

    comment = factory.Faker('text')

osfstorage_settings = apps.get_app_config('addons_osfstorage')

generic_location = {
    'service': 'cloud',
    osfstorage_settings.WATERBUTLER_RESOURCE: 'resource',
    'object': '1615307',
}

generic_waterbutler_settings = {
    'storage': {
        'provider': 'glowcloud',
        'container': 'osf_storage',
        'use_public': True,
    }
}

generic_waterbutler_credentials = {
    'storage': {
        'region': 'PartsUnknown',
        'username': 'mankind',
        'token': 'heresmrsocko'
    }
}

class RegionFactory(DjangoModelFactory):
    class Meta:
        model = Region

    name = factory.Sequence(lambda n: 'Region {0}'.format(n))
    _id = factory.Sequence(lambda n: 'us_east_{0}'.format(n))
    waterbutler_credentials = generic_waterbutler_credentials
    waterbutler_settings = generic_waterbutler_settings
    waterbutler_url = 'http://123.456.test.woo'

class ProviderAssetFileFactory(DjangoModelFactory):
    class Meta:
        model = models.ProviderAssetFile

    name = FuzzyChoice(choices=PROVIDER_ASSET_NAME_CHOICES)
    file = factory.django.FileField(filename=factory.Faker('text'))

    @classmethod
    def _create(cls, target_class, *args, **kwargs):
        providers = kwargs.pop('providers', [])
        instance = super(ProviderAssetFileFactory, cls)._create(target_class, *args, **kwargs)
        instance.providers.add(*providers)
        instance.save()
        return instance

class ChronosJournalFactory(DjangoModelFactory):
    class Meta:
        model = models.ChronosJournal

    name = factory.Faker('company')
    title = factory.Faker('sentence')
    journal_id = factory.Faker('ean')

    @classmethod
    def _create(cls, target_class, *args, **kwargs):
        kwargs['raw_response'] = kwargs.get('raw_response', {
            'TITLE': kwargs.get('title', factory.Faker('sentence').generate([])),
            'JOURNAL_ID': kwargs.get('title', factory.Faker('ean').generate([])),
            'NAME': kwargs.get('name', factory.Faker('company').generate([])),
            'JOURNAL_URL': factory.Faker('url').generate([]),
            'PUBLISHER_ID': factory.Faker('ean').generate([]),
            'PUBLISHER_NAME': factory.Faker('name').generate([])
            # Other stuff too probably
        })
        instance = super(ChronosJournalFactory, cls)._create(target_class, *args, **kwargs)
        instance.save()
        return instance

class ChronosSubmissionFactory(DjangoModelFactory):
    class Meta:
        model = models.ChronosSubmission

    publication_id = factory.Faker('ean')
    journal = factory.SubFactory(ChronosJournalFactory)
    preprint = factory.SubFactory(PreprintFactory)
    submitter = factory.SubFactory(AuthUserFactory)
    status = factory.Faker('random_int', min=1, max=5)
    submission_url = factory.Faker('url')

    @classmethod
    def _create(cls, target_class, *args, **kwargs):
        kwargs['raw_response'] = kwargs.get('raw_response', {
            'PUBLICATION_ID': kwargs.get('publication_id', factory.Faker('ean').generate([])),
            'STATUS_CODE': kwargs.get('status', factory.Faker('random_int', min=1, max=5).generate([])),
            'CHRONOS_SUBMISSION_URL': kwargs.get('submission_url', factory.Faker('url').generate([])),
            # Other stuff too probably
        })
        instance = super(ChronosSubmissionFactory, cls)._create(target_class, *args, **kwargs)
        instance.save()
        return instance

class BrandFactory(DjangoModelFactory):
    class Meta:
        model = models.Brand

    # just limiting it to 30 chars
    name = factory.LazyAttribute(lambda n: fake.company()[:29])

    hero_logo_image = factory.Faker('url')
    topnav_logo_image = factory.Faker('url')
    hero_background_image = factory.Faker('url')

    primary_color = factory.Faker('hex_color')
    secondary_color = factory.Faker('hex_color')

class SchemaResponseFactory(DjangoModelFactory):
    initiator = factory.SubFactory(AuthUserFactory)
    revision_justification = "We're talkin' about practice!"
    submitted_timestamp = FuzzyDateTime(datetime.datetime(1970, 1, 1, tzinfo=pytz.UTC))
    registration = factory.SubFactory(RegistrationFactory)

    class Meta:
        model = models.SchemaResponse

    @classmethod
    def _create(cls, *args, **kwargs):
        from django.contrib.contenttypes.models import ContentType
        SchemaResponse = models.SchemaResponse
        justification = kwargs.get('revision_justification')
        initiator = kwargs.get('initiator')
        registration = kwargs.get('registration')
        content_type = ContentType.objects.get_for_model(registration)
        schema = registration.registered_schema.get()
        if not registration.schema_responses.exists():
            return SchemaResponse.create_initial_response(initiator, registration, schema, justification)
        else:
            previous_schema_response = SchemaResponse.objects.filter(
                object_id=registration.id,
                content_type_id=content_type
            ).get()
            previous_schema_response.approvals_state_machine.set_state(ApprovalStates.APPROVED)
            previous_schema_response.save()
            return SchemaResponse.create_from_previous_response(initiator, previous_schema_response, justification)

class SchemaResponseActionFactory(DjangoModelFactory):
    class Meta:
        model = models.SchemaResponseAction

    trigger = FuzzyChoice(choices=SchemaResponseTriggers.char_field_choices())
    comment = factory.Faker('text')
    from_state = FuzzyChoice(choices=ApprovalStates.char_field_choices())
    to_state = FuzzyChoice(choices=ApprovalStates.char_field_choices())

    target = factory.SubFactory(SchemaResponseFactory)
    creator = factory.SubFactory(AuthUserFactory)

    is_deleted = False

class RegistrationBulkUploadJobFactory(DjangoModelFactory):
    class Meta:
        model = models.RegistrationBulkUploadJob

class RegistrationBulkUploadRowFactory(DjangoModelFactory):
    class Meta:
        model = models.RegistrationBulkUploadRow

redpajama_set_name: RedPajamaGithub